xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs_lport.c (revision 17c201b3)
17725ccfdSJing Huang /*
2a36c61f9SKrishna Gudipati  * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
37725ccfdSJing Huang  * All rights reserved
47725ccfdSJing Huang  * www.brocade.com
57725ccfdSJing Huang  *
67725ccfdSJing Huang  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
77725ccfdSJing Huang  *
87725ccfdSJing Huang  * This program is free software; you can redistribute it and/or modify it
97725ccfdSJing Huang  * under the terms of the GNU General Public License (GPL) Version 2 as
107725ccfdSJing Huang  * published by the Free Software Foundation
117725ccfdSJing Huang  *
127725ccfdSJing Huang  * This program is distributed in the hope that it will be useful, but
137725ccfdSJing Huang  * WITHOUT ANY WARRANTY; without even the implied warranty of
147725ccfdSJing Huang  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
157725ccfdSJing Huang  * General Public License for more details.
167725ccfdSJing Huang  */
177725ccfdSJing Huang 
18f16a1750SMaggie Zhang #include "bfad_drv.h"
197826f304SKrishna Gudipati #include "bfad_im.h"
20a36c61f9SKrishna Gudipati #include "bfa_fcs.h"
21a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h"
22a36c61f9SKrishna Gudipati #include "bfa_fc.h"
237725ccfdSJing Huang 
247725ccfdSJing Huang BFA_TRC_FILE(FCS, PORT);
257725ccfdSJing Huang 
26a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port,
277725ccfdSJing Huang 					 struct fchs_s *rx_fchs, u8 reason_code,
287725ccfdSJing Huang 					 u8 reason_code_expl);
29a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
30a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, struct fc_logi_s *plogi);
31a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port);
32a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port);
33a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port);
34a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port);
35a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port);
36a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port);
37a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port,
387725ccfdSJing Huang 			struct fchs_s *rx_fchs,
397725ccfdSJing Huang 			struct fc_echo_s *echo, u16 len);
40a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port,
417725ccfdSJing Huang 			struct fchs_s *rx_fchs,
427725ccfdSJing Huang 			struct fc_rnid_cmd_s *rnid, u16 len);
43a36c61f9SKrishna Gudipati static void     bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
447725ccfdSJing Huang 			struct fc_rnid_general_topology_data_s *gen_topo_data);
457725ccfdSJing Huang 
46a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port);
47a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port);
48a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port);
49a36c61f9SKrishna Gudipati 
50a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port);
51a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port);
52a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port);
53a36c61f9SKrishna Gudipati 
547725ccfdSJing Huang static struct {
55a36c61f9SKrishna Gudipati 	void		(*init) (struct bfa_fcs_lport_s *port);
56a36c61f9SKrishna Gudipati 	void		(*online) (struct bfa_fcs_lport_s *port);
57a36c61f9SKrishna Gudipati 	void		(*offline) (struct bfa_fcs_lport_s *port);
587725ccfdSJing Huang } __port_action[] = {
597725ccfdSJing Huang 	{
60a36c61f9SKrishna Gudipati 	bfa_fcs_lport_unknown_init, bfa_fcs_lport_unknown_online,
61a36c61f9SKrishna Gudipati 			bfa_fcs_lport_unknown_offline}, {
62a36c61f9SKrishna Gudipati 	bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online,
63a36c61f9SKrishna Gudipati 			bfa_fcs_lport_fab_offline}, {
64a36c61f9SKrishna Gudipati 	bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online,
65a36c61f9SKrishna Gudipati 			bfa_fcs_lport_n2n_offline},
66a36c61f9SKrishna Gudipati 	};
677725ccfdSJing Huang 
685fbe25c7SJing Huang /*
697725ccfdSJing Huang  *  fcs_port_sm FCS logical port state machine
707725ccfdSJing Huang  */
717725ccfdSJing Huang 
72a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event {
737725ccfdSJing Huang 	BFA_FCS_PORT_SM_CREATE = 1,
747725ccfdSJing Huang 	BFA_FCS_PORT_SM_ONLINE = 2,
757725ccfdSJing Huang 	BFA_FCS_PORT_SM_OFFLINE = 3,
767725ccfdSJing Huang 	BFA_FCS_PORT_SM_DELETE = 4,
777725ccfdSJing Huang 	BFA_FCS_PORT_SM_DELRPORT = 5,
78dd5aaf45SKrishna Gudipati 	BFA_FCS_PORT_SM_STOP = 6,
797725ccfdSJing Huang };
807725ccfdSJing Huang 
81a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port,
82a36c61f9SKrishna Gudipati 					enum bfa_fcs_lport_event event);
83a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port,
84a36c61f9SKrishna Gudipati 					enum bfa_fcs_lport_event event);
85a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s *port,
86a36c61f9SKrishna Gudipati 					enum bfa_fcs_lport_event event);
87a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port,
88a36c61f9SKrishna Gudipati 					enum bfa_fcs_lport_event event);
89a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port,
90a36c61f9SKrishna Gudipati 					enum bfa_fcs_lport_event event);
91dd5aaf45SKrishna Gudipati static void	bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
92dd5aaf45SKrishna Gudipati 					enum bfa_fcs_lport_event event);
937725ccfdSJing Huang 
947725ccfdSJing Huang static void
95a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_uninit(
96a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
97a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
987725ccfdSJing Huang {
997725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1007725ccfdSJing Huang 	bfa_trc(port->fcs, event);
1017725ccfdSJing Huang 
1027725ccfdSJing Huang 	switch (event) {
1037725ccfdSJing Huang 	case BFA_FCS_PORT_SM_CREATE:
104a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
1057725ccfdSJing Huang 		break;
1067725ccfdSJing Huang 
1077725ccfdSJing Huang 	default:
108e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1097725ccfdSJing Huang 	}
1107725ccfdSJing Huang }
1117725ccfdSJing Huang 
1127725ccfdSJing Huang static void
113a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port,
114a36c61f9SKrishna Gudipati 			enum bfa_fcs_lport_event event)
1157725ccfdSJing Huang {
1167725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1177725ccfdSJing Huang 	bfa_trc(port->fcs, event);
1187725ccfdSJing Huang 
1197725ccfdSJing Huang 	switch (event) {
1207725ccfdSJing Huang 	case BFA_FCS_PORT_SM_ONLINE:
121a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
122a36c61f9SKrishna Gudipati 		bfa_fcs_lport_online_actions(port);
1237725ccfdSJing Huang 		break;
1247725ccfdSJing Huang 
1257725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELETE:
126a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
127a36c61f9SKrishna Gudipati 		bfa_fcs_lport_deleted(port);
1287725ccfdSJing Huang 		break;
1297725ccfdSJing Huang 
130dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_STOP:
131dd5aaf45SKrishna Gudipati 		/* If vport - send completion call back */
132dd5aaf45SKrishna Gudipati 		if (port->vport)
133dd5aaf45SKrishna Gudipati 			bfa_fcs_vport_stop_comp(port->vport);
134dd5aaf45SKrishna Gudipati 		break;
135dd5aaf45SKrishna Gudipati 
1363e98cc01SJing Huang 	case BFA_FCS_PORT_SM_OFFLINE:
1373e98cc01SJing Huang 		break;
1383e98cc01SJing Huang 
1397725ccfdSJing Huang 	default:
140e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1417725ccfdSJing Huang 	}
1427725ccfdSJing Huang }
1437725ccfdSJing Huang 
1447725ccfdSJing Huang static void
145a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_online(
146a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
147a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
1487725ccfdSJing Huang {
1497725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
1507725ccfdSJing Huang 	struct list_head		*qe, *qen;
1517725ccfdSJing Huang 
1527725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1537725ccfdSJing Huang 	bfa_trc(port->fcs, event);
1547725ccfdSJing Huang 
1557725ccfdSJing Huang 	switch (event) {
1567725ccfdSJing Huang 	case BFA_FCS_PORT_SM_OFFLINE:
157a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_offline);
158a36c61f9SKrishna Gudipati 		bfa_fcs_lport_offline_actions(port);
1597725ccfdSJing Huang 		break;
1607725ccfdSJing Huang 
161dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_STOP:
162dd5aaf45SKrishna Gudipati 		__port_action[port->fabric->fab_type].offline(port);
163dd5aaf45SKrishna Gudipati 
164dd5aaf45SKrishna Gudipati 		if (port->num_rports == 0) {
165dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
166dd5aaf45SKrishna Gudipati 			/* If vport - send completion call back */
167dd5aaf45SKrishna Gudipati 			if (port->vport)
168dd5aaf45SKrishna Gudipati 				bfa_fcs_vport_stop_comp(port->vport);
169dd5aaf45SKrishna Gudipati 		} else {
170dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
171dd5aaf45SKrishna Gudipati 			list_for_each_safe(qe, qen, &port->rport_q) {
172dd5aaf45SKrishna Gudipati 				rport = (struct bfa_fcs_rport_s *) qe;
173dd5aaf45SKrishna Gudipati 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
174dd5aaf45SKrishna Gudipati 			}
175dd5aaf45SKrishna Gudipati 		}
176dd5aaf45SKrishna Gudipati 		break;
177dd5aaf45SKrishna Gudipati 
1787725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELETE:
1797725ccfdSJing Huang 
1807725ccfdSJing Huang 		__port_action[port->fabric->fab_type].offline(port);
1817725ccfdSJing Huang 
1827725ccfdSJing Huang 		if (port->num_rports == 0) {
183a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
184a36c61f9SKrishna Gudipati 			bfa_fcs_lport_deleted(port);
1857725ccfdSJing Huang 		} else {
186a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
1877725ccfdSJing Huang 			list_for_each_safe(qe, qen, &port->rport_q) {
1887725ccfdSJing Huang 				rport = (struct bfa_fcs_rport_s *) qe;
189f7f73812SMaggie Zhang 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1907725ccfdSJing Huang 			}
1917725ccfdSJing Huang 		}
1927725ccfdSJing Huang 		break;
1937725ccfdSJing Huang 
1947725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELRPORT:
1957725ccfdSJing Huang 		break;
1967725ccfdSJing Huang 
1977725ccfdSJing Huang 	default:
198e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1997725ccfdSJing Huang 	}
2007725ccfdSJing Huang }
2017725ccfdSJing Huang 
2027725ccfdSJing Huang static void
203a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_offline(
204a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
205a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
2067725ccfdSJing Huang {
2077725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
2087725ccfdSJing Huang 	struct list_head		*qe, *qen;
2097725ccfdSJing Huang 
2107725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2117725ccfdSJing Huang 	bfa_trc(port->fcs, event);
2127725ccfdSJing Huang 
2137725ccfdSJing Huang 	switch (event) {
2147725ccfdSJing Huang 	case BFA_FCS_PORT_SM_ONLINE:
215a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
216a36c61f9SKrishna Gudipati 		bfa_fcs_lport_online_actions(port);
2177725ccfdSJing Huang 		break;
2187725ccfdSJing Huang 
219dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_STOP:
220dd5aaf45SKrishna Gudipati 		if (port->num_rports == 0) {
221dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
222dd5aaf45SKrishna Gudipati 			/* If vport - send completion call back */
223dd5aaf45SKrishna Gudipati 			if (port->vport)
224dd5aaf45SKrishna Gudipati 				bfa_fcs_vport_stop_comp(port->vport);
225dd5aaf45SKrishna Gudipati 		} else {
226dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
227dd5aaf45SKrishna Gudipati 			list_for_each_safe(qe, qen, &port->rport_q) {
228dd5aaf45SKrishna Gudipati 				rport = (struct bfa_fcs_rport_s *) qe;
229dd5aaf45SKrishna Gudipati 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
230dd5aaf45SKrishna Gudipati 			}
231dd5aaf45SKrishna Gudipati 		}
232dd5aaf45SKrishna Gudipati 		break;
233dd5aaf45SKrishna Gudipati 
2347725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELETE:
2357725ccfdSJing Huang 		if (port->num_rports == 0) {
236a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
237a36c61f9SKrishna Gudipati 			bfa_fcs_lport_deleted(port);
2387725ccfdSJing Huang 		} else {
239a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
2407725ccfdSJing Huang 			list_for_each_safe(qe, qen, &port->rport_q) {
2417725ccfdSJing Huang 				rport = (struct bfa_fcs_rport_s *) qe;
242f7f73812SMaggie Zhang 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
2437725ccfdSJing Huang 			}
2447725ccfdSJing Huang 		}
2457725ccfdSJing Huang 		break;
2467725ccfdSJing Huang 
2477725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELRPORT:
2487725ccfdSJing Huang 	case BFA_FCS_PORT_SM_OFFLINE:
2497725ccfdSJing Huang 		break;
2507725ccfdSJing Huang 
2517725ccfdSJing Huang 	default:
252e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
2537725ccfdSJing Huang 	}
2547725ccfdSJing Huang }
2557725ccfdSJing Huang 
2567725ccfdSJing Huang static void
257dd5aaf45SKrishna Gudipati bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
258dd5aaf45SKrishna Gudipati 			  enum bfa_fcs_lport_event event)
259dd5aaf45SKrishna Gudipati {
260dd5aaf45SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
261dd5aaf45SKrishna Gudipati 	bfa_trc(port->fcs, event);
262dd5aaf45SKrishna Gudipati 
263dd5aaf45SKrishna Gudipati 	switch (event) {
264dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_DELRPORT:
265dd5aaf45SKrishna Gudipati 		if (port->num_rports == 0) {
266dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
267dd5aaf45SKrishna Gudipati 			/* If vport - send completion call back */
268dd5aaf45SKrishna Gudipati 			if (port->vport)
269dd5aaf45SKrishna Gudipati 				bfa_fcs_vport_stop_comp(port->vport);
270dd5aaf45SKrishna Gudipati 		}
271dd5aaf45SKrishna Gudipati 		break;
272dd5aaf45SKrishna Gudipati 
273dd5aaf45SKrishna Gudipati 	default:
274dd5aaf45SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
275dd5aaf45SKrishna Gudipati 	}
276dd5aaf45SKrishna Gudipati }
277dd5aaf45SKrishna Gudipati 
278dd5aaf45SKrishna Gudipati static void
279a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_deleting(
280a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
281a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
2827725ccfdSJing Huang {
2837725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2847725ccfdSJing Huang 	bfa_trc(port->fcs, event);
2857725ccfdSJing Huang 
2867725ccfdSJing Huang 	switch (event) {
2877725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELRPORT:
2887725ccfdSJing Huang 		if (port->num_rports == 0) {
289a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
290a36c61f9SKrishna Gudipati 			bfa_fcs_lport_deleted(port);
2917725ccfdSJing Huang 		}
2927725ccfdSJing Huang 		break;
2937725ccfdSJing Huang 
2947725ccfdSJing Huang 	default:
295e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
2967725ccfdSJing Huang 	}
2977725ccfdSJing Huang }
2987725ccfdSJing Huang 
2995fbe25c7SJing Huang /*
3007725ccfdSJing Huang  *  fcs_port_pvt
3017725ccfdSJing Huang  */
3027725ccfdSJing Huang 
3037725ccfdSJing Huang /*
3047826f304SKrishna Gudipati  * Send AEN notification
3057826f304SKrishna Gudipati  */
3067826f304SKrishna Gudipati static void
3077826f304SKrishna Gudipati bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port,
3087826f304SKrishna Gudipati 			enum bfa_lport_aen_event event)
3097826f304SKrishna Gudipati {
3107826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
3117826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
3127826f304SKrishna Gudipati 
3137826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
3147826f304SKrishna Gudipati 	if (!aen_entry)
3157826f304SKrishna Gudipati 		return;
3167826f304SKrishna Gudipati 
3177826f304SKrishna Gudipati 	aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
3187826f304SKrishna Gudipati 	aen_entry->aen_data.lport.roles = port->port_cfg.roles;
3197826f304SKrishna Gudipati 	aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
3207826f304SKrishna Gudipati 					bfa_fcs_get_base_port(port->fcs));
3217826f304SKrishna Gudipati 	aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
3227826f304SKrishna Gudipati 
3237826f304SKrishna Gudipati 	/* Send the AEN notification */
3247826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
3257826f304SKrishna Gudipati 				  BFA_AEN_CAT_LPORT, event);
3267826f304SKrishna Gudipati }
3277826f304SKrishna Gudipati 
3287826f304SKrishna Gudipati /*
3297725ccfdSJing Huang  * Send a LS reject
3307725ccfdSJing Huang  */
3317725ccfdSJing Huang static void
332a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
3337725ccfdSJing Huang 			 u8 reason_code, u8 reason_code_expl)
3347725ccfdSJing Huang {
3357725ccfdSJing Huang 	struct fchs_s	fchs;
3367725ccfdSJing Huang 	struct bfa_fcxp_s *fcxp;
3377725ccfdSJing Huang 	struct bfa_rport_s *bfa_rport = NULL;
3387725ccfdSJing Huang 	int		len;
3397725ccfdSJing Huang 
340a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
3417725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
3427725ccfdSJing Huang 
3437725ccfdSJing Huang 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
3447725ccfdSJing Huang 	if (!fcxp)
3457725ccfdSJing Huang 		return;
3467725ccfdSJing Huang 
347a36c61f9SKrishna Gudipati 	len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
348a36c61f9SKrishna Gudipati 			      rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
349a36c61f9SKrishna Gudipati 			      rx_fchs->ox_id, reason_code, reason_code_expl);
3507725ccfdSJing Huang 
3517725ccfdSJing Huang 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
3527725ccfdSJing Huang 			  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
3537725ccfdSJing Huang 			  FC_MAX_PDUSZ, 0);
3547725ccfdSJing Huang }
3557725ccfdSJing Huang 
3565fbe25c7SJing Huang /*
357d7be54ccSKrishna Gudipati  * Send a FCCT Reject
358d7be54ccSKrishna Gudipati  */
359d7be54ccSKrishna Gudipati static void
360d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port,
361d7be54ccSKrishna Gudipati 	struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl)
362d7be54ccSKrishna Gudipati {
363d7be54ccSKrishna Gudipati 	struct fchs_s   fchs;
364d7be54ccSKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
365d7be54ccSKrishna Gudipati 	struct bfa_rport_s *bfa_rport = NULL;
366d7be54ccSKrishna Gudipati 	int             len;
367d7be54ccSKrishna Gudipati 	struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1);
368d7be54ccSKrishna Gudipati 	struct ct_hdr_s *ct_hdr;
369d7be54ccSKrishna Gudipati 
370d7be54ccSKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
371d7be54ccSKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
372d7be54ccSKrishna Gudipati 
373d7be54ccSKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
374d7be54ccSKrishna Gudipati 	if (!fcxp)
375d7be54ccSKrishna Gudipati 		return;
376d7be54ccSKrishna Gudipati 
377d7be54ccSKrishna Gudipati 	ct_hdr = bfa_fcxp_get_reqbuf(fcxp);
378d7be54ccSKrishna Gudipati 	ct_hdr->gs_type = rx_cthdr->gs_type;
379d7be54ccSKrishna Gudipati 	ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type;
380d7be54ccSKrishna Gudipati 
381d7be54ccSKrishna Gudipati 	len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id,
382d7be54ccSKrishna Gudipati 			bfa_fcs_lport_get_fcid(port),
383d7be54ccSKrishna Gudipati 			rx_fchs->ox_id, reason_code, reason_code_expl);
384d7be54ccSKrishna Gudipati 
385d7be54ccSKrishna Gudipati 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
386d7be54ccSKrishna Gudipati 			BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
387d7be54ccSKrishna Gudipati 			FC_MAX_PDUSZ, 0);
388d7be54ccSKrishna Gudipati }
389d7be54ccSKrishna Gudipati 
390d7be54ccSKrishna Gudipati /*
3917725ccfdSJing Huang  * Process incoming plogi from a remote port.
3927725ccfdSJing Huang  */
3937725ccfdSJing Huang static void
394a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
395a36c61f9SKrishna Gudipati 		struct fchs_s *rx_fchs, struct fc_logi_s *plogi)
3967725ccfdSJing Huang {
3977725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
3987725ccfdSJing Huang 
3997725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->d_id);
4007725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
4017725ccfdSJing Huang 
4027725ccfdSJing Huang 	/*
4037725ccfdSJing Huang 	 * If min cfg mode is enabled, drop any incoming PLOGIs
4047725ccfdSJing Huang 	 */
4057725ccfdSJing Huang 	if (__fcs_min_cfg(port->fcs)) {
4067725ccfdSJing Huang 		bfa_trc(port->fcs, rx_fchs->s_id);
4077725ccfdSJing Huang 		return;
4087725ccfdSJing Huang 	}
4097725ccfdSJing Huang 
4107725ccfdSJing Huang 	if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
4117725ccfdSJing Huang 		bfa_trc(port->fcs, rx_fchs->s_id);
4127725ccfdSJing Huang 		/*
4137725ccfdSJing Huang 		 * send a LS reject
4147725ccfdSJing Huang 		 */
415a36c61f9SKrishna Gudipati 		bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
4167725ccfdSJing Huang 					FC_LS_RJT_RSN_PROTOCOL_ERROR,
4177725ccfdSJing Huang 					FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS);
4187725ccfdSJing Huang 		return;
4197725ccfdSJing Huang 	}
4207725ccfdSJing Huang 
4215fbe25c7SJing Huang 	/*
4227725ccfdSJing Huang 	 * Direct Attach P2P mode : verify address assigned by the r-port.
4237725ccfdSJing Huang 	 */
424a36c61f9SKrishna Gudipati 	if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
425a36c61f9SKrishna Gudipati 		(memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
426a36c61f9SKrishna Gudipati 			   (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
4277725ccfdSJing Huang 		if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
428a36c61f9SKrishna Gudipati 			/* Address assigned to us cannot be a WKA */
429a36c61f9SKrishna Gudipati 			bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
4307725ccfdSJing Huang 					FC_LS_RJT_RSN_PROTOCOL_ERROR,
4317725ccfdSJing Huang 					FC_LS_RJT_EXP_INVALID_NPORT_ID);
4327725ccfdSJing Huang 			return;
4337725ccfdSJing Huang 		}
4347725ccfdSJing Huang 		port->pid  = rx_fchs->d_id;
435b704495cSKrishna Gudipati 		bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
4367725ccfdSJing Huang 	}
4377725ccfdSJing Huang 
4385fbe25c7SJing Huang 	/*
4397725ccfdSJing Huang 	 * First, check if we know the device by pwwn.
4407725ccfdSJing Huang 	 */
441a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name);
4427725ccfdSJing Huang 	if (rport) {
4435fbe25c7SJing Huang 		/*
444a36c61f9SKrishna Gudipati 		 * Direct Attach P2P mode : handle address assigned by r-port.
4457725ccfdSJing Huang 		 */
446a36c61f9SKrishna Gudipati 		if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
447a36c61f9SKrishna Gudipati 			(memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
4487725ccfdSJing Huang 			(void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
4497725ccfdSJing Huang 			port->pid  = rx_fchs->d_id;
450b704495cSKrishna Gudipati 			bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
4517725ccfdSJing Huang 			rport->pid = rx_fchs->s_id;
4527725ccfdSJing Huang 		}
4537725ccfdSJing Huang 		bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
4547725ccfdSJing Huang 		return;
4557725ccfdSJing Huang 	}
4567725ccfdSJing Huang 
4575fbe25c7SJing Huang 	/*
4587725ccfdSJing Huang 	 * Next, lookup rport by PID.
4597725ccfdSJing Huang 	 */
460a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id);
4617725ccfdSJing Huang 	if (!rport) {
4625fbe25c7SJing Huang 		/*
4637725ccfdSJing Huang 		 * Inbound PLOGI from a new device.
4647725ccfdSJing Huang 		 */
4657725ccfdSJing Huang 		bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
4667725ccfdSJing Huang 		return;
4677725ccfdSJing Huang 	}
4687725ccfdSJing Huang 
4695fbe25c7SJing Huang 	/*
4707725ccfdSJing Huang 	 * Rport is known only by PID.
4717725ccfdSJing Huang 	 */
4727725ccfdSJing Huang 	if (rport->pwwn) {
4735fbe25c7SJing Huang 		/*
4747725ccfdSJing Huang 		 * This is a different device with the same pid. Old device
4757725ccfdSJing Huang 		 * disappeared. Send implicit LOGO to old device.
4767725ccfdSJing Huang 		 */
477d4b671c5SJing Huang 		WARN_ON(rport->pwwn == plogi->port_name);
478f7f73812SMaggie Zhang 		bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
4797725ccfdSJing Huang 
4805fbe25c7SJing Huang 		/*
4817725ccfdSJing Huang 		 * Inbound PLOGI from a new device (with old PID).
4827725ccfdSJing Huang 		 */
4837725ccfdSJing Huang 		bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
4847725ccfdSJing Huang 		return;
4857725ccfdSJing Huang 	}
4867725ccfdSJing Huang 
4875fbe25c7SJing Huang 	/*
4887725ccfdSJing Huang 	 * PLOGI crossing each other.
4897725ccfdSJing Huang 	 */
490d4b671c5SJing Huang 	WARN_ON(rport->pwwn != WWN_NULL);
4917725ccfdSJing Huang 	bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
4927725ccfdSJing Huang }
4937725ccfdSJing Huang 
4947725ccfdSJing Huang /*
4957725ccfdSJing Huang  * Process incoming ECHO.
4967725ccfdSJing Huang  * Since it does not require a login, it is processed here.
4977725ccfdSJing Huang  */
4987725ccfdSJing Huang static void
499a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
5007725ccfdSJing Huang 		struct fc_echo_s *echo, u16 rx_len)
5017725ccfdSJing Huang {
5027725ccfdSJing Huang 	struct fchs_s		fchs;
5037725ccfdSJing Huang 	struct bfa_fcxp_s	*fcxp;
5047725ccfdSJing Huang 	struct bfa_rport_s	*bfa_rport = NULL;
5057725ccfdSJing Huang 	int			len, pyld_len;
5067725ccfdSJing Huang 
5077725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
5087725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->d_id);
5097725ccfdSJing Huang 
5107725ccfdSJing Huang 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
5117725ccfdSJing Huang 	if (!fcxp)
5127725ccfdSJing Huang 		return;
5137725ccfdSJing Huang 
514a36c61f9SKrishna Gudipati 	len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
515a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
516a36c61f9SKrishna Gudipati 				rx_fchs->ox_id);
5177725ccfdSJing Huang 
5187725ccfdSJing Huang 	/*
5197725ccfdSJing Huang 	 * Copy the payload (if any) from the echo frame
5207725ccfdSJing Huang 	 */
5217725ccfdSJing Huang 	pyld_len = rx_len - sizeof(struct fchs_s);
522a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_len);
5237725ccfdSJing Huang 	bfa_trc(port->fcs, pyld_len);
5247725ccfdSJing Huang 
5257725ccfdSJing Huang 	if (pyld_len > len)
5267725ccfdSJing Huang 		memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
5277725ccfdSJing Huang 			sizeof(struct fc_echo_s), (echo + 1),
5287725ccfdSJing Huang 			(pyld_len - sizeof(struct fc_echo_s)));
5297725ccfdSJing Huang 
5307725ccfdSJing Huang 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
5317725ccfdSJing Huang 			BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
5327725ccfdSJing Huang 			FC_MAX_PDUSZ, 0);
5337725ccfdSJing Huang }
5347725ccfdSJing Huang 
5357725ccfdSJing Huang /*
5367725ccfdSJing Huang  * Process incoming RNID.
5377725ccfdSJing Huang  * Since it does not require a login, it is processed here.
5387725ccfdSJing Huang  */
5397725ccfdSJing Huang static void
540a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
5417725ccfdSJing Huang 		struct fc_rnid_cmd_s *rnid, u16 rx_len)
5427725ccfdSJing Huang {
5437725ccfdSJing Huang 	struct fc_rnid_common_id_data_s common_id_data;
5447725ccfdSJing Huang 	struct fc_rnid_general_topology_data_s gen_topo_data;
5457725ccfdSJing Huang 	struct fchs_s	fchs;
5467725ccfdSJing Huang 	struct bfa_fcxp_s *fcxp;
5477725ccfdSJing Huang 	struct bfa_rport_s *bfa_rport = NULL;
5487725ccfdSJing Huang 	u16	len;
5497725ccfdSJing Huang 	u32	data_format;
5507725ccfdSJing Huang 
5517725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
5527725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->d_id);
5537725ccfdSJing Huang 	bfa_trc(port->fcs, rx_len);
5547725ccfdSJing Huang 
5557725ccfdSJing Huang 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
5567725ccfdSJing Huang 	if (!fcxp)
5577725ccfdSJing Huang 		return;
5587725ccfdSJing Huang 
5597725ccfdSJing Huang 	/*
5607725ccfdSJing Huang 	 * Check Node Indentification Data Format
5617725ccfdSJing Huang 	 * We only support General Topology Discovery Format.
5627725ccfdSJing Huang 	 * For any other requested Data Formats, we return Common Node Id Data
5637725ccfdSJing Huang 	 * only, as per FC-LS.
5647725ccfdSJing Huang 	 */
5657725ccfdSJing Huang 	bfa_trc(port->fcs, rnid->node_id_data_format);
5667725ccfdSJing Huang 	if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
5677725ccfdSJing Huang 		data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
5687725ccfdSJing Huang 		/*
5697725ccfdSJing Huang 		 * Get General topology data for this port
5707725ccfdSJing Huang 		 */
5717725ccfdSJing Huang 		bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
5727725ccfdSJing Huang 	} else {
5737725ccfdSJing Huang 		data_format = RNID_NODEID_DATA_FORMAT_COMMON;
5747725ccfdSJing Huang 	}
5757725ccfdSJing Huang 
5767725ccfdSJing Huang 	/*
5777725ccfdSJing Huang 	 * Copy the Node Id Info
5787725ccfdSJing Huang 	 */
579a36c61f9SKrishna Gudipati 	common_id_data.port_name = bfa_fcs_lport_get_pwwn(port);
580a36c61f9SKrishna Gudipati 	common_id_data.node_name = bfa_fcs_lport_get_nwwn(port);
5817725ccfdSJing Huang 
582a36c61f9SKrishna Gudipati 	len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
583a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
584a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, data_format, &common_id_data,
585a36c61f9SKrishna Gudipati 				&gen_topo_data);
5867725ccfdSJing Huang 
5877725ccfdSJing Huang 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
5887725ccfdSJing Huang 			BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
5897725ccfdSJing Huang 			FC_MAX_PDUSZ, 0);
5907725ccfdSJing Huang }
5917725ccfdSJing Huang 
5927725ccfdSJing Huang /*
5937725ccfdSJing Huang  *  Fill out General Topolpgy Discovery Data for RNID ELS.
5947725ccfdSJing Huang  */
5957725ccfdSJing Huang static void
596a36c61f9SKrishna Gudipati bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
5977725ccfdSJing Huang 			struct fc_rnid_general_topology_data_s *gen_topo_data)
5987725ccfdSJing Huang {
5996a18b167SJing Huang 	memset(gen_topo_data, 0,
6007725ccfdSJing Huang 		      sizeof(struct fc_rnid_general_topology_data_s));
6017725ccfdSJing Huang 
602ba816ea8SJing Huang 	gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST);
6037725ccfdSJing Huang 	gen_topo_data->phy_port_num = 0;	/* @todo */
604ba816ea8SJing Huang 	gen_topo_data->num_attached_nodes = cpu_to_be32(1);
6057725ccfdSJing Huang }
6067725ccfdSJing Huang 
6077725ccfdSJing Huang static void
608a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
6097725ccfdSJing Huang {
610a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
611a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
612a36c61f9SKrishna Gudipati 
6137725ccfdSJing Huang 	bfa_trc(port->fcs, port->fabric->oper_type);
6147725ccfdSJing Huang 
6157725ccfdSJing Huang 	__port_action[port->fabric->fab_type].init(port);
6167725ccfdSJing Huang 	__port_action[port->fabric->fab_type].online(port);
6177725ccfdSJing Huang 
618a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
61988166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
620a36c61f9SKrishna Gudipati 		"Logical port online: WWN = %s Role = %s\n",
621a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
6227826f304SKrishna Gudipati 	bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE);
623a36c61f9SKrishna Gudipati 
624a36c61f9SKrishna Gudipati 	bfad->bfad_flags |= BFAD_PORT_ONLINE;
6257725ccfdSJing Huang }
6267725ccfdSJing Huang 
6277725ccfdSJing Huang static void
628a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
6297725ccfdSJing Huang {
6307725ccfdSJing Huang 	struct list_head	*qe, *qen;
6317725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
632a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
633a36c61f9SKrishna Gudipati 	char    lpwwn_buf[BFA_STRING_32];
6347725ccfdSJing Huang 
6357725ccfdSJing Huang 	bfa_trc(port->fcs, port->fabric->oper_type);
6367725ccfdSJing Huang 
6377725ccfdSJing Huang 	__port_action[port->fabric->fab_type].offline(port);
6387725ccfdSJing Huang 
639a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
640f7f73812SMaggie Zhang 	if (bfa_sm_cmp_state(port->fabric,
6417826f304SKrishna Gudipati 			bfa_fcs_fabric_sm_online) == BFA_TRUE) {
64288166242SJing Huang 		BFA_LOG(KERN_ERR, bfad, bfa_log_level,
643a36c61f9SKrishna Gudipati 		"Logical port lost fabric connectivity: WWN = %s Role = %s\n",
644a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
6457826f304SKrishna Gudipati 		bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
6467826f304SKrishna Gudipati 	} else {
64788166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
648a36c61f9SKrishna Gudipati 		"Logical port taken offline: WWN = %s Role = %s\n",
649a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
6507826f304SKrishna Gudipati 		bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE);
6517826f304SKrishna Gudipati 	}
6527725ccfdSJing Huang 
6537725ccfdSJing Huang 	list_for_each_safe(qe, qen, &port->rport_q) {
6547725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
655f7f73812SMaggie Zhang 		bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
6567725ccfdSJing Huang 	}
6577725ccfdSJing Huang }
6587725ccfdSJing Huang 
6597725ccfdSJing Huang static void
660a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port)
6617725ccfdSJing Huang {
662d4b671c5SJing Huang 	WARN_ON(1);
6637725ccfdSJing Huang }
6647725ccfdSJing Huang 
6657725ccfdSJing Huang static void
666a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port)
6677725ccfdSJing Huang {
668d4b671c5SJing Huang 	WARN_ON(1);
6697725ccfdSJing Huang }
6707725ccfdSJing Huang 
6717725ccfdSJing Huang static void
672a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port)
6737725ccfdSJing Huang {
674d4b671c5SJing Huang 	WARN_ON(1);
6757725ccfdSJing Huang }
6767725ccfdSJing Huang 
6777725ccfdSJing Huang static void
678a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs)
6797725ccfdSJing Huang {
680a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
681a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
682a36c61f9SKrishna Gudipati 	int		len;
6837725ccfdSJing Huang 
684a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
685a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
686a36c61f9SKrishna Gudipati 
687a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
688a36c61f9SKrishna Gudipati 	if (!fcxp)
689a36c61f9SKrishna Gudipati 		return;
690a36c61f9SKrishna Gudipati 
691a36c61f9SKrishna Gudipati 	len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
692a36c61f9SKrishna Gudipati 			rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
693a36c61f9SKrishna Gudipati 			rx_fchs->ox_id, 0);
694a36c61f9SKrishna Gudipati 
695a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
696a36c61f9SKrishna Gudipati 			  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
697a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, 0);
698a36c61f9SKrishna Gudipati }
699a36c61f9SKrishna Gudipati static void
700a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
701a36c61f9SKrishna Gudipati {
702a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
703a36c61f9SKrishna Gudipati 	char    lpwwn_buf[BFA_STRING_32];
704a36c61f9SKrishna Gudipati 
705a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
70688166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
707a36c61f9SKrishna Gudipati 		"Logical port deleted: WWN = %s Role = %s\n",
708a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
7097826f304SKrishna Gudipati 	bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE);
710a36c61f9SKrishna Gudipati 
711a36c61f9SKrishna Gudipati 	/* Base port will be deleted by the OS driver */
71217c201b3SKrishna Gudipati 	if (port->vport)
7137725ccfdSJing Huang 		bfa_fcs_vport_delete_comp(port->vport);
71417c201b3SKrishna Gudipati 	else
715f7f73812SMaggie Zhang 		bfa_wc_down(&port->fabric->wc);
7167725ccfdSJing Huang }
7177725ccfdSJing Huang 
7187725ccfdSJing Huang 
7195fbe25c7SJing Huang /*
7207725ccfdSJing Huang  * Unsolicited frame receive handling.
7217725ccfdSJing Huang  */
7227725ccfdSJing Huang void
723a36c61f9SKrishna Gudipati bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
724a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
7257725ccfdSJing Huang {
7267725ccfdSJing Huang 	u32	pid = fchs->s_id;
7277725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport = NULL;
7287725ccfdSJing Huang 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
7297725ccfdSJing Huang 
7307725ccfdSJing Huang 	bfa_stats(lport, uf_recvs);
73115821f05SKrishna Gudipati 	bfa_trc(lport->fcs, fchs->type);
7327725ccfdSJing Huang 
733a36c61f9SKrishna Gudipati 	if (!bfa_fcs_lport_is_online(lport)) {
7347725ccfdSJing Huang 		bfa_stats(lport, uf_recv_drops);
7357725ccfdSJing Huang 		return;
7367725ccfdSJing Huang 	}
7377725ccfdSJing Huang 
7385fbe25c7SJing Huang 	/*
7397725ccfdSJing Huang 	 * First, handle ELSs that donot require a login.
7407725ccfdSJing Huang 	 */
7417725ccfdSJing Huang 	/*
7427725ccfdSJing Huang 	 * Handle PLOGI first
7437725ccfdSJing Huang 	 */
7447725ccfdSJing Huang 	if ((fchs->type == FC_TYPE_ELS) &&
7457725ccfdSJing Huang 		(els_cmd->els_code == FC_ELS_PLOGI)) {
746a36c61f9SKrishna Gudipati 		bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
7477725ccfdSJing Huang 		return;
7487725ccfdSJing Huang 	}
7497725ccfdSJing Huang 
7507725ccfdSJing Huang 	/*
7517725ccfdSJing Huang 	 * Handle ECHO separately.
7527725ccfdSJing Huang 	 */
7537725ccfdSJing Huang 	if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
754a36c61f9SKrishna Gudipati 		bfa_fcs_lport_echo(lport, fchs,
7557725ccfdSJing Huang 				(struct fc_echo_s *)els_cmd, len);
7567725ccfdSJing Huang 		return;
7577725ccfdSJing Huang 	}
7587725ccfdSJing Huang 
7597725ccfdSJing Huang 	/*
7607725ccfdSJing Huang 	 * Handle RNID separately.
7617725ccfdSJing Huang 	 */
7627725ccfdSJing Huang 	if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
763a36c61f9SKrishna Gudipati 		bfa_fcs_lport_rnid(lport, fchs,
7647725ccfdSJing Huang 			(struct fc_rnid_cmd_s *) els_cmd, len);
7657725ccfdSJing Huang 		return;
7667725ccfdSJing Huang 	}
7677725ccfdSJing Huang 
768a36c61f9SKrishna Gudipati 	if (fchs->type == FC_TYPE_BLS) {
769a36c61f9SKrishna Gudipati 		if ((fchs->routing == FC_RTG_BASIC_LINK) &&
770a36c61f9SKrishna Gudipati 				(fchs->cat_info == FC_CAT_ABTS))
771a36c61f9SKrishna Gudipati 			bfa_fcs_lport_abts_acc(lport, fchs);
772a36c61f9SKrishna Gudipati 		return;
773a36c61f9SKrishna Gudipati 	}
774d7be54ccSKrishna Gudipati 
775d7be54ccSKrishna Gudipati 	if (fchs->type == FC_TYPE_SERVICES) {
776d7be54ccSKrishna Gudipati 		/*
777d7be54ccSKrishna Gudipati 		 * Unhandled FC-GS frames. Send a FC-CT Reject
778d7be54ccSKrishna Gudipati 		 */
779d7be54ccSKrishna Gudipati 		bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP,
780d7be54ccSKrishna Gudipati 				CT_NS_EXP_NOADDITIONAL);
781d7be54ccSKrishna Gudipati 		return;
782d7be54ccSKrishna Gudipati 	}
783d7be54ccSKrishna Gudipati 
7845fbe25c7SJing Huang 	/*
7857725ccfdSJing Huang 	 * look for a matching remote port ID
7867725ccfdSJing Huang 	 */
787a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pid(lport, pid);
7887725ccfdSJing Huang 	if (rport) {
7897725ccfdSJing Huang 		bfa_trc(rport->fcs, fchs->s_id);
7907725ccfdSJing Huang 		bfa_trc(rport->fcs, fchs->d_id);
7917725ccfdSJing Huang 		bfa_trc(rport->fcs, fchs->type);
7927725ccfdSJing Huang 
7937725ccfdSJing Huang 		bfa_fcs_rport_uf_recv(rport, fchs, len);
7947725ccfdSJing Huang 		return;
7957725ccfdSJing Huang 	}
7967725ccfdSJing Huang 
7975fbe25c7SJing Huang 	/*
7987725ccfdSJing Huang 	 * Only handles ELS frames for now.
7997725ccfdSJing Huang 	 */
8007725ccfdSJing Huang 	if (fchs->type != FC_TYPE_ELS) {
80115821f05SKrishna Gudipati 		bfa_trc(lport->fcs, fchs->s_id);
80215821f05SKrishna Gudipati 		bfa_trc(lport->fcs, fchs->d_id);
80315821f05SKrishna Gudipati 		/* ignore type FC_TYPE_FC_FSS */
80415821f05SKrishna Gudipati 		if (fchs->type != FC_TYPE_FC_FSS)
80515821f05SKrishna Gudipati 			bfa_sm_fault(lport->fcs, fchs->type);
8067725ccfdSJing Huang 		return;
8077725ccfdSJing Huang 	}
8087725ccfdSJing Huang 
8097725ccfdSJing Huang 	bfa_trc(lport->fcs, els_cmd->els_code);
8107725ccfdSJing Huang 	if (els_cmd->els_code == FC_ELS_RSCN) {
811a36c61f9SKrishna Gudipati 		bfa_fcs_lport_scn_process_rscn(lport, fchs, len);
8127725ccfdSJing Huang 		return;
8137725ccfdSJing Huang 	}
8147725ccfdSJing Huang 
8157725ccfdSJing Huang 	if (els_cmd->els_code == FC_ELS_LOGO) {
8165fbe25c7SJing Huang 		/*
8177725ccfdSJing Huang 		 * @todo Handle LOGO frames received.
8187725ccfdSJing Huang 		 */
8197725ccfdSJing Huang 		return;
8207725ccfdSJing Huang 	}
8217725ccfdSJing Huang 
8227725ccfdSJing Huang 	if (els_cmd->els_code == FC_ELS_PRLI) {
8235fbe25c7SJing Huang 		/*
8247725ccfdSJing Huang 		 * @todo Handle PRLI frames received.
8257725ccfdSJing Huang 		 */
8267725ccfdSJing Huang 		return;
8277725ccfdSJing Huang 	}
8287725ccfdSJing Huang 
8295fbe25c7SJing Huang 	/*
8307725ccfdSJing Huang 	 * Unhandled ELS frames. Send a LS_RJT.
8317725ccfdSJing Huang 	 */
832a36c61f9SKrishna Gudipati 	bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
8337725ccfdSJing Huang 				 FC_LS_RJT_EXP_NO_ADDL_INFO);
8347725ccfdSJing Huang 
8357725ccfdSJing Huang }
8367725ccfdSJing Huang 
8375fbe25c7SJing Huang /*
8387725ccfdSJing Huang  *   PID based Lookup for a R-Port in the Port R-Port Queue
8397725ccfdSJing Huang  */
8407725ccfdSJing Huang struct bfa_fcs_rport_s *
841a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid)
8427725ccfdSJing Huang {
8437725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
8447725ccfdSJing Huang 	struct list_head	*qe;
8457725ccfdSJing Huang 
8467725ccfdSJing Huang 	list_for_each(qe, &port->rport_q) {
8477725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
8487725ccfdSJing Huang 		if (rport->pid == pid)
8497725ccfdSJing Huang 			return rport;
8507725ccfdSJing Huang 	}
8517725ccfdSJing Huang 
8527725ccfdSJing Huang 	bfa_trc(port->fcs, pid);
8537725ccfdSJing Huang 	return NULL;
8547725ccfdSJing Huang }
8557725ccfdSJing Huang 
8565fbe25c7SJing Huang /*
8577725ccfdSJing Huang  *   PWWN based Lookup for a R-Port in the Port R-Port Queue
8587725ccfdSJing Huang  */
8597725ccfdSJing Huang struct bfa_fcs_rport_s *
860a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn)
8617725ccfdSJing Huang {
8627725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
8637725ccfdSJing Huang 	struct list_head	*qe;
8647725ccfdSJing Huang 
8657725ccfdSJing Huang 	list_for_each(qe, &port->rport_q) {
8667725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
8677725ccfdSJing Huang 		if (wwn_is_equal(rport->pwwn, pwwn))
8687725ccfdSJing Huang 			return rport;
8697725ccfdSJing Huang 	}
8707725ccfdSJing Huang 
8717725ccfdSJing Huang 	bfa_trc(port->fcs, pwwn);
872f8ceafdeSJing Huang 	return NULL;
8737725ccfdSJing Huang }
8747725ccfdSJing Huang 
8755fbe25c7SJing Huang /*
8767725ccfdSJing Huang  *   NWWN based Lookup for a R-Port in the Port R-Port Queue
8777725ccfdSJing Huang  */
8787725ccfdSJing Huang struct bfa_fcs_rport_s *
879a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn)
8807725ccfdSJing Huang {
8817725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
8827725ccfdSJing Huang 	struct list_head	*qe;
8837725ccfdSJing Huang 
8847725ccfdSJing Huang 	list_for_each(qe, &port->rport_q) {
8857725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
8867725ccfdSJing Huang 		if (wwn_is_equal(rport->nwwn, nwwn))
8877725ccfdSJing Huang 			return rport;
8887725ccfdSJing Huang 	}
8897725ccfdSJing Huang 
8907725ccfdSJing Huang 	bfa_trc(port->fcs, nwwn);
891f8ceafdeSJing Huang 	return NULL;
8927725ccfdSJing Huang }
8937725ccfdSJing Huang 
8945fbe25c7SJing Huang /*
8957725ccfdSJing Huang  * Called by rport module when new rports are discovered.
8967725ccfdSJing Huang  */
8977725ccfdSJing Huang void
898a36c61f9SKrishna Gudipati bfa_fcs_lport_add_rport(
899a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
9007725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport)
9017725ccfdSJing Huang {
9027725ccfdSJing Huang 	list_add_tail(&rport->qe, &port->rport_q);
9037725ccfdSJing Huang 	port->num_rports++;
9047725ccfdSJing Huang }
9057725ccfdSJing Huang 
9065fbe25c7SJing Huang /*
9077725ccfdSJing Huang  * Called by rport module to when rports are deleted.
9087725ccfdSJing Huang  */
9097725ccfdSJing Huang void
910a36c61f9SKrishna Gudipati bfa_fcs_lport_del_rport(
911a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
9127725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport)
9137725ccfdSJing Huang {
914d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport));
9157725ccfdSJing Huang 	list_del(&rport->qe);
9167725ccfdSJing Huang 	port->num_rports--;
9177725ccfdSJing Huang 
9187725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
9197725ccfdSJing Huang }
9207725ccfdSJing Huang 
9215fbe25c7SJing Huang /*
9227725ccfdSJing Huang  * Called by fabric for base port when fabric login is complete.
9237725ccfdSJing Huang  * Called by vport for virtual ports when FDISC is complete.
9247725ccfdSJing Huang  */
9257725ccfdSJing Huang void
926a36c61f9SKrishna Gudipati bfa_fcs_lport_online(struct bfa_fcs_lport_s *port)
9277725ccfdSJing Huang {
9287725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
9297725ccfdSJing Huang }
9307725ccfdSJing Huang 
9315fbe25c7SJing Huang /*
9327725ccfdSJing Huang  * Called by fabric for base port when fabric goes offline.
9337725ccfdSJing Huang  * Called by vport for virtual ports when virtual port becomes offline.
9347725ccfdSJing Huang  */
9357725ccfdSJing Huang void
936a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port)
9377725ccfdSJing Huang {
9387725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
9397725ccfdSJing Huang }
9407725ccfdSJing Huang 
9415fbe25c7SJing Huang /*
9427725ccfdSJing Huang  * Called by fabric to delete base lport and associated resources.
9437725ccfdSJing Huang  *
9447725ccfdSJing Huang  * Called by vport to delete lport and associated resources. Should call
9457725ccfdSJing Huang  * bfa_fcs_vport_delete_comp() for vports on completion.
9467725ccfdSJing Huang  */
9477725ccfdSJing Huang void
948a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port)
9497725ccfdSJing Huang {
9507725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
9517725ccfdSJing Huang }
9527725ccfdSJing Huang 
9535fbe25c7SJing Huang /*
9547725ccfdSJing Huang  * Return TRUE if port is online, else return FALSE
9557725ccfdSJing Huang  */
9567725ccfdSJing Huang bfa_boolean_t
957a36c61f9SKrishna Gudipati bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port)
9587725ccfdSJing Huang {
959a36c61f9SKrishna Gudipati 	return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online);
9607725ccfdSJing Huang }
9617725ccfdSJing Huang 
9625fbe25c7SJing Huang /*
963e6714324SKrishna Gudipati   * Attach time initialization of logical ports.
9647725ccfdSJing Huang  */
9657725ccfdSJing Huang void
966a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs,
967a36c61f9SKrishna Gudipati 		   u16 vf_id, struct bfa_fcs_vport_s *vport)
9687725ccfdSJing Huang {
9697725ccfdSJing Huang 	lport->fcs = fcs;
9707725ccfdSJing Huang 	lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
9717725ccfdSJing Huang 	lport->vport = vport;
9723fd45980SKrishna Gudipati 	lport->lp_tag = (vport) ? vport->lps->bfa_tag :
9733fd45980SKrishna Gudipati 				  lport->fabric->lps->bfa_tag;
9747725ccfdSJing Huang 
9757725ccfdSJing Huang 	INIT_LIST_HEAD(&lport->rport_q);
9767725ccfdSJing Huang 	lport->num_rports = 0;
977e6714324SKrishna Gudipati }
9787725ccfdSJing Huang 
9795fbe25c7SJing Huang /*
980e6714324SKrishna Gudipati  * Logical port initialization of base or virtual port.
981e6714324SKrishna Gudipati  * Called by fabric for base port or by vport for virtual ports.
982e6714324SKrishna Gudipati  */
983e6714324SKrishna Gudipati 
984e6714324SKrishna Gudipati void
985a36c61f9SKrishna Gudipati bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
986a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg)
987e6714324SKrishna Gudipati {
988e6714324SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = lport->vport;
989a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad;
990a36c61f9SKrishna Gudipati 	char    lpwwn_buf[BFA_STRING_32];
991e6714324SKrishna Gudipati 
9926a18b167SJing Huang 	lport->port_cfg = *port_cfg;
993e6714324SKrishna Gudipati 
994a36c61f9SKrishna Gudipati 	lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport,
995e6714324SKrishna Gudipati 					lport->port_cfg.roles,
9967725ccfdSJing Huang 					lport->fabric->vf_drv,
9977725ccfdSJing Huang 					vport ? vport->vport_drv : NULL);
998e6714324SKrishna Gudipati 
999a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport));
100088166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
1001a36c61f9SKrishna Gudipati 		"New logical port created: WWN = %s Role = %s\n",
1002a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
10037826f304SKrishna Gudipati 	bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW);
10047725ccfdSJing Huang 
1005a36c61f9SKrishna Gudipati 	bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit);
10067725ccfdSJing Huang 	bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
10077725ccfdSJing Huang }
10087725ccfdSJing Huang 
10095fbe25c7SJing Huang /*
10107725ccfdSJing Huang  *  fcs_lport_api
10117725ccfdSJing Huang  */
10127725ccfdSJing Huang 
10137725ccfdSJing Huang void
1014a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr(
1015a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
1016a36c61f9SKrishna Gudipati 	struct bfa_lport_attr_s *port_attr)
10177725ccfdSJing Huang {
1018a36c61f9SKrishna Gudipati 	if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
10197725ccfdSJing Huang 		port_attr->pid = port->pid;
10207725ccfdSJing Huang 	else
10217725ccfdSJing Huang 		port_attr->pid = 0;
10227725ccfdSJing Huang 
10237725ccfdSJing Huang 	port_attr->port_cfg = port->port_cfg;
10247725ccfdSJing Huang 
10257725ccfdSJing Huang 	if (port->fabric) {
1026f7f73812SMaggie Zhang 		port_attr->port_type = port->fabric->oper_type;
1027da99dcc9SMaggie Zhang 		port_attr->loopback = bfa_sm_cmp_state(port->fabric,
1028da99dcc9SMaggie Zhang 				bfa_fcs_fabric_sm_loopback);
1029f926a05fSKrishna Gudipati 		port_attr->authfail =
1030f7f73812SMaggie Zhang 			bfa_sm_cmp_state(port->fabric,
1031f7f73812SMaggie Zhang 				bfa_fcs_fabric_sm_auth_failed);
1032a36c61f9SKrishna Gudipati 		port_attr->fabric_name  = bfa_fcs_lport_get_fabric_name(port);
10337725ccfdSJing Huang 		memcpy(port_attr->fabric_ip_addr,
1034a36c61f9SKrishna Gudipati 			bfa_fcs_lport_get_fabric_ipaddr(port),
10357725ccfdSJing Huang 			BFA_FCS_FABRIC_IPADDR_SZ);
10367725ccfdSJing Huang 
103786e32dabSKrishna Gudipati 		if (port->vport != NULL) {
1038a36c61f9SKrishna Gudipati 			port_attr->port_type = BFA_PORT_TYPE_VPORT;
103986e32dabSKrishna Gudipati 			port_attr->fpma_mac =
1040f7f73812SMaggie Zhang 				port->vport->lps->lp_mac;
1041a36c61f9SKrishna Gudipati 		} else {
104286e32dabSKrishna Gudipati 			port_attr->fpma_mac =
1043f7f73812SMaggie Zhang 				port->fabric->lps->lp_mac;
1044a36c61f9SKrishna Gudipati 		}
1045a36c61f9SKrishna Gudipati 	} else {
1046a36c61f9SKrishna Gudipati 		port_attr->port_type = BFA_PORT_TYPE_UNKNOWN;
1047a36c61f9SKrishna Gudipati 		port_attr->state = BFA_LPORT_UNINIT;
1048a36c61f9SKrishna Gudipati 	}
1049a36c61f9SKrishna Gudipati }
1050a36c61f9SKrishna Gudipati 
10515fbe25c7SJing Huang /*
1052a36c61f9SKrishna Gudipati  *  bfa_fcs_lport_fab port fab functions
1053a36c61f9SKrishna Gudipati  */
1054a36c61f9SKrishna Gudipati 
10555fbe25c7SJing Huang /*
1056a36c61f9SKrishna Gudipati  *   Called by port to initialize fabric services of the base port.
1057a36c61f9SKrishna Gudipati  */
1058a36c61f9SKrishna Gudipati static void
1059a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port)
1060a36c61f9SKrishna Gudipati {
1061a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ns_init(port);
1062a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_init(port);
1063a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ms_init(port);
1064a36c61f9SKrishna Gudipati }
1065a36c61f9SKrishna Gudipati 
10665fbe25c7SJing Huang /*
1067a36c61f9SKrishna Gudipati  *   Called by port to notify transition to online state.
1068a36c61f9SKrishna Gudipati  */
1069a36c61f9SKrishna Gudipati static void
1070a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
1071a36c61f9SKrishna Gudipati {
1072a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ns_online(port);
1073a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_online(port);
1074a36c61f9SKrishna Gudipati }
1075a36c61f9SKrishna Gudipati 
10765fbe25c7SJing Huang /*
1077a36c61f9SKrishna Gudipati  *   Called by port to notify transition to offline state.
1078a36c61f9SKrishna Gudipati  */
1079a36c61f9SKrishna Gudipati static void
1080a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port)
1081a36c61f9SKrishna Gudipati {
1082a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ns_offline(port);
1083a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_offline(port);
1084a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ms_offline(port);
1085a36c61f9SKrishna Gudipati }
1086a36c61f9SKrishna Gudipati 
10875fbe25c7SJing Huang /*
1088a36c61f9SKrishna Gudipati  *  bfa_fcs_lport_n2n  functions
1089a36c61f9SKrishna Gudipati  */
1090a36c61f9SKrishna Gudipati 
10915fbe25c7SJing Huang /*
1092a36c61f9SKrishna Gudipati  *   Called by fcs/port to initialize N2N topology.
1093a36c61f9SKrishna Gudipati  */
1094a36c61f9SKrishna Gudipati static void
1095a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port)
1096a36c61f9SKrishna Gudipati {
1097a36c61f9SKrishna Gudipati }
1098a36c61f9SKrishna Gudipati 
10995fbe25c7SJing Huang /*
1100a36c61f9SKrishna Gudipati  *   Called by fcs/port to notify transition to online state.
1101a36c61f9SKrishna Gudipati  */
1102a36c61f9SKrishna Gudipati static void
1103a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
1104a36c61f9SKrishna Gudipati {
1105a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1106a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *pcfg = &port->port_cfg;
1107a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
1108a36c61f9SKrishna Gudipati 
1109a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, pcfg->pwwn);
1110a36c61f9SKrishna Gudipati 
1111a36c61f9SKrishna Gudipati 	/*
1112a36c61f9SKrishna Gudipati 	 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
1113a36c61f9SKrishna Gudipati 	 * and assign an Address. if not, we need to wait for its PLOGI.
1114a36c61f9SKrishna Gudipati 	 *
1115a36c61f9SKrishna Gudipati 	 * If our PWWN is < than that of the remote port, it will send a PLOGI
1116a36c61f9SKrishna Gudipati 	 * with the PIDs assigned. The rport state machine take care of this
1117a36c61f9SKrishna Gudipati 	 * incoming PLOGI.
1118a36c61f9SKrishna Gudipati 	 */
1119a36c61f9SKrishna Gudipati 	if (memcmp
1120a36c61f9SKrishna Gudipati 	    ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
1121a36c61f9SKrishna Gudipati 	     sizeof(wwn_t)) > 0) {
1122a36c61f9SKrishna Gudipati 		port->pid = N2N_LOCAL_PID;
1123b704495cSKrishna Gudipati 		bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID);
11245fbe25c7SJing Huang 		/*
1125a36c61f9SKrishna Gudipati 		 * First, check if we know the device by pwwn.
1126a36c61f9SKrishna Gudipati 		 */
1127a36c61f9SKrishna Gudipati 		rport = bfa_fcs_lport_get_rport_by_pwwn(port,
1128a36c61f9SKrishna Gudipati 							n2n_port->rem_port_wwn);
1129a36c61f9SKrishna Gudipati 		if (rport) {
1130a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rport->pid);
1131a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rport->pwwn);
1132a36c61f9SKrishna Gudipati 			rport->pid = N2N_REMOTE_PID;
1133f7f73812SMaggie Zhang 			bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
1134a36c61f9SKrishna Gudipati 			return;
1135a36c61f9SKrishna Gudipati 		}
1136a36c61f9SKrishna Gudipati 
1137a36c61f9SKrishna Gudipati 		/*
1138a36c61f9SKrishna Gudipati 		 * In n2n there can be only one rport. Delete the old one
1139a36c61f9SKrishna Gudipati 		 * whose pid should be zero, because it is offline.
1140a36c61f9SKrishna Gudipati 		 */
1141a36c61f9SKrishna Gudipati 		if (port->num_rports > 0) {
1142a36c61f9SKrishna Gudipati 			rport = bfa_fcs_lport_get_rport_by_pid(port, 0);
1143d4b671c5SJing Huang 			WARN_ON(rport == NULL);
1144a36c61f9SKrishna Gudipati 			if (rport) {
1145a36c61f9SKrishna Gudipati 				bfa_trc(port->fcs, rport->pwwn);
1146f7f73812SMaggie Zhang 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1147a36c61f9SKrishna Gudipati 			}
1148a36c61f9SKrishna Gudipati 		}
1149a36c61f9SKrishna Gudipati 		bfa_fcs_rport_create(port, N2N_REMOTE_PID);
1150a36c61f9SKrishna Gudipati 	}
1151a36c61f9SKrishna Gudipati }
1152a36c61f9SKrishna Gudipati 
11535fbe25c7SJing Huang /*
1154a36c61f9SKrishna Gudipati  *   Called by fcs/port to notify transition to offline state.
1155a36c61f9SKrishna Gudipati  */
1156a36c61f9SKrishna Gudipati static void
1157a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
1158a36c61f9SKrishna Gudipati {
1159a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1160a36c61f9SKrishna Gudipati 
1161a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
1162a36c61f9SKrishna Gudipati 	port->pid = 0;
1163a36c61f9SKrishna Gudipati 	n2n_port->rem_port_wwn = 0;
1164a36c61f9SKrishna Gudipati 	n2n_port->reply_oxid = 0;
1165a36c61f9SKrishna Gudipati }
1166a36c61f9SKrishna Gudipati 
1167a36c61f9SKrishna Gudipati #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
1168a36c61f9SKrishna Gudipati 
1169a36c61f9SKrishna Gudipati /*
1170a36c61f9SKrishna Gudipati  * forward declarations
1171a36c61f9SKrishna Gudipati  */
1172a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg,
1173a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
1174a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg,
1175a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
1176a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg,
1177a36c61f9SKrishna Gudipati 					   struct bfa_fcxp_s *fcxp_alloced);
1178a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_rhba_response(void *fcsarg,
1179a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
1180a36c61f9SKrishna Gudipati 						void *cbarg,
1181a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
1182a36c61f9SKrishna Gudipati 						u32 rsp_len,
1183a36c61f9SKrishna Gudipati 						u32 resid_len,
1184a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
1185a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_rprt_response(void *fcsarg,
1186a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
1187a36c61f9SKrishna Gudipati 						void *cbarg,
1188a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
1189a36c61f9SKrishna Gudipati 						u32 rsp_len,
1190a36c61f9SKrishna Gudipati 						u32 resid_len,
1191a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
1192a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_rpa_response(void *fcsarg,
1193a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
1194a36c61f9SKrishna Gudipati 					       void *cbarg,
1195a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
1196a36c61f9SKrishna Gudipati 					       u32 rsp_len,
1197a36c61f9SKrishna Gudipati 					       u32 resid_len,
1198a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
1199a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_timeout(void *arg);
1200a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1201a36c61f9SKrishna Gudipati 						  u8 *pyld);
1202a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1203a36c61f9SKrishna Gudipati 						  u8 *pyld);
1204a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1205a36c61f9SKrishna Gudipati 						 u8 *pyld);
1206a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *
1207a36c61f9SKrishna Gudipati 						       fdmi, u8 *pyld);
1208a36c61f9SKrishna Gudipati static void	bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1209a36c61f9SKrishna Gudipati 				 struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
1210a36c61f9SKrishna Gudipati static void	bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1211a36c61f9SKrishna Gudipati 				  struct bfa_fcs_fdmi_port_attr_s *port_attr);
1212d7be54ccSKrishna Gudipati u32	bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed);
1213d7be54ccSKrishna Gudipati 
12145fbe25c7SJing Huang /*
1215a36c61f9SKrishna Gudipati  *  fcs_fdmi_sm FCS FDMI state machine
1216a36c61f9SKrishna Gudipati  */
1217a36c61f9SKrishna Gudipati 
12185fbe25c7SJing Huang /*
1219a36c61f9SKrishna Gudipati  *  FDMI State Machine events
1220a36c61f9SKrishna Gudipati  */
1221a36c61f9SKrishna Gudipati enum port_fdmi_event {
1222a36c61f9SKrishna Gudipati 	FDMISM_EVENT_PORT_ONLINE = 1,
1223a36c61f9SKrishna Gudipati 	FDMISM_EVENT_PORT_OFFLINE = 2,
1224a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RSP_OK = 4,
1225a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RSP_ERROR = 5,
1226a36c61f9SKrishna Gudipati 	FDMISM_EVENT_TIMEOUT = 6,
1227a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RHBA_SENT = 7,
1228a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RPRT_SENT = 8,
1229a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RPA_SENT = 9,
1230a36c61f9SKrishna Gudipati };
1231a36c61f9SKrishna Gudipati 
1232a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1233a36c61f9SKrishna Gudipati 					     enum port_fdmi_event event);
1234a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_sending_rhba(
1235a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1236a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1237a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1238a36c61f9SKrishna Gudipati 					  enum port_fdmi_event event);
1239a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rhba_retry(
1240a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1241a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1242a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_sending_rprt(
1243a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1244a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1245a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1246a36c61f9SKrishna Gudipati 					  enum port_fdmi_event event);
1247a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rprt_retry(
1248a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1249a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1250a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_sending_rpa(
1251a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1252a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1253a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1254a36c61f9SKrishna Gudipati 					 enum port_fdmi_event event);
1255a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rpa_retry(
1256a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1257a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1258a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1259a36c61f9SKrishna Gudipati 					    enum port_fdmi_event event);
1260a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_disabled(
1261a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1262a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
12635fbe25c7SJing Huang /*
1264a36c61f9SKrishna Gudipati  *	Start in offline state - awaiting MS to send start.
1265a36c61f9SKrishna Gudipati  */
1266a36c61f9SKrishna Gudipati static void
1267a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1268a36c61f9SKrishna Gudipati 			     enum port_fdmi_event event)
1269a36c61f9SKrishna Gudipati {
1270a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1271a36c61f9SKrishna Gudipati 
1272a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1273a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1274a36c61f9SKrishna Gudipati 
1275a36c61f9SKrishna Gudipati 	fdmi->retry_cnt = 0;
1276a36c61f9SKrishna Gudipati 
1277a36c61f9SKrishna Gudipati 	switch (event) {
1278a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_ONLINE:
1279a36c61f9SKrishna Gudipati 		if (port->vport) {
1280a36c61f9SKrishna Gudipati 			/*
1281a36c61f9SKrishna Gudipati 			 * For Vports, register a new port.
1282a36c61f9SKrishna Gudipati 			 */
1283a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1284a36c61f9SKrishna Gudipati 					 bfa_fcs_lport_fdmi_sm_sending_rprt);
1285a36c61f9SKrishna Gudipati 			bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1286a36c61f9SKrishna Gudipati 		} else {
1287a36c61f9SKrishna Gudipati 			/*
1288a36c61f9SKrishna Gudipati 			 * For a base port, we should first register the HBA
128925985edcSLucas De Marchi 			 * attribute. The HBA attribute also contains the base
1290a36c61f9SKrishna Gudipati 			 *  port registration.
1291a36c61f9SKrishna Gudipati 			 */
1292a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1293a36c61f9SKrishna Gudipati 					 bfa_fcs_lport_fdmi_sm_sending_rhba);
1294a36c61f9SKrishna Gudipati 			bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1295a36c61f9SKrishna Gudipati 		}
1296a36c61f9SKrishna Gudipati 		break;
1297a36c61f9SKrishna Gudipati 
1298a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1299a36c61f9SKrishna Gudipati 		break;
1300a36c61f9SKrishna Gudipati 
1301a36c61f9SKrishna Gudipati 	default:
1302a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1303a36c61f9SKrishna Gudipati 	}
1304a36c61f9SKrishna Gudipati }
1305a36c61f9SKrishna Gudipati 
1306a36c61f9SKrishna Gudipati static void
1307a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1308a36c61f9SKrishna Gudipati 				  enum port_fdmi_event event)
1309a36c61f9SKrishna Gudipati {
1310a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1311a36c61f9SKrishna Gudipati 
1312a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1313a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1314a36c61f9SKrishna Gudipati 
1315a36c61f9SKrishna Gudipati 	switch (event) {
1316a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RHBA_SENT:
1317a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba);
1318a36c61f9SKrishna Gudipati 		break;
1319a36c61f9SKrishna Gudipati 
1320a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1321a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1322a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1323a36c61f9SKrishna Gudipati 					   &fdmi->fcxp_wqe);
1324a36c61f9SKrishna Gudipati 		break;
1325a36c61f9SKrishna Gudipati 
1326a36c61f9SKrishna Gudipati 	default:
1327a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1328a36c61f9SKrishna Gudipati 	}
1329a36c61f9SKrishna Gudipati }
1330a36c61f9SKrishna Gudipati 
1331a36c61f9SKrishna Gudipati static void
1332a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1333a36c61f9SKrishna Gudipati 			enum port_fdmi_event event)
1334a36c61f9SKrishna Gudipati {
1335a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1336a36c61f9SKrishna Gudipati 
1337a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1338a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1339a36c61f9SKrishna Gudipati 
1340a36c61f9SKrishna Gudipati 	switch (event) {
1341a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_ERROR:
1342a36c61f9SKrishna Gudipati 		/*
1343a36c61f9SKrishna Gudipati 		 * if max retries have not been reached, start timer for a
1344a36c61f9SKrishna Gudipati 		 * delayed retry
1345a36c61f9SKrishna Gudipati 		 */
1346a36c61f9SKrishna Gudipati 		if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1347a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1348a36c61f9SKrishna Gudipati 					bfa_fcs_lport_fdmi_sm_rhba_retry);
1349a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1350a36c61f9SKrishna Gudipati 					    &fdmi->timer,
1351a36c61f9SKrishna Gudipati 					    bfa_fcs_lport_fdmi_timeout, fdmi,
1352a36c61f9SKrishna Gudipati 					    BFA_FCS_RETRY_TIMEOUT);
1353a36c61f9SKrishna Gudipati 		} else {
1354a36c61f9SKrishna Gudipati 			/*
1355a36c61f9SKrishna Gudipati 			 * set state to offline
1356a36c61f9SKrishna Gudipati 			 */
1357a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1358a36c61f9SKrishna Gudipati 		}
1359a36c61f9SKrishna Gudipati 		break;
1360a36c61f9SKrishna Gudipati 
1361a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_OK:
1362a36c61f9SKrishna Gudipati 		/*
1363a36c61f9SKrishna Gudipati 		 * Initiate Register Port Attributes
1364a36c61f9SKrishna Gudipati 		 */
1365a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1366a36c61f9SKrishna Gudipati 		fdmi->retry_cnt = 0;
1367a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1368a36c61f9SKrishna Gudipati 		break;
1369a36c61f9SKrishna Gudipati 
1370a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1371a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(fdmi->fcxp);
1372a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1373a36c61f9SKrishna Gudipati 		break;
1374a36c61f9SKrishna Gudipati 
1375a36c61f9SKrishna Gudipati 	default:
1376a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1377a36c61f9SKrishna Gudipati 	}
1378a36c61f9SKrishna Gudipati }
1379a36c61f9SKrishna Gudipati 
1380a36c61f9SKrishna Gudipati static void
1381a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1382a36c61f9SKrishna Gudipati 				enum port_fdmi_event event)
1383a36c61f9SKrishna Gudipati {
1384a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1385a36c61f9SKrishna Gudipati 
1386a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1387a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1388a36c61f9SKrishna Gudipati 
1389a36c61f9SKrishna Gudipati 	switch (event) {
1390a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_TIMEOUT:
1391a36c61f9SKrishna Gudipati 		/*
1392a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
1393a36c61f9SKrishna Gudipati 		 */
1394a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba);
1395a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1396a36c61f9SKrishna Gudipati 		break;
1397a36c61f9SKrishna Gudipati 
1398a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1399a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1400a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fdmi->timer);
1401a36c61f9SKrishna Gudipati 		break;
1402a36c61f9SKrishna Gudipati 
1403a36c61f9SKrishna Gudipati 	default:
1404a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1405a36c61f9SKrishna Gudipati 	}
1406a36c61f9SKrishna Gudipati }
1407a36c61f9SKrishna Gudipati 
1408a36c61f9SKrishna Gudipati /*
1409a36c61f9SKrishna Gudipati * RPRT : Register Port
1410a36c61f9SKrishna Gudipati  */
1411a36c61f9SKrishna Gudipati static void
1412a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1413a36c61f9SKrishna Gudipati 				  enum port_fdmi_event event)
1414a36c61f9SKrishna Gudipati {
1415a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1416a36c61f9SKrishna Gudipati 
1417a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1418a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1419a36c61f9SKrishna Gudipati 
1420a36c61f9SKrishna Gudipati 	switch (event) {
1421a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RPRT_SENT:
1422a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt);
1423a36c61f9SKrishna Gudipati 		break;
1424a36c61f9SKrishna Gudipati 
1425a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1426a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1427a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1428a36c61f9SKrishna Gudipati 					   &fdmi->fcxp_wqe);
1429a36c61f9SKrishna Gudipati 		break;
1430a36c61f9SKrishna Gudipati 
1431a36c61f9SKrishna Gudipati 	default:
1432a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1433a36c61f9SKrishna Gudipati 	}
1434a36c61f9SKrishna Gudipati }
1435a36c61f9SKrishna Gudipati 
1436a36c61f9SKrishna Gudipati static void
1437a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1438a36c61f9SKrishna Gudipati 			enum port_fdmi_event event)
1439a36c61f9SKrishna Gudipati {
1440a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1441a36c61f9SKrishna Gudipati 
1442a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1443a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1444a36c61f9SKrishna Gudipati 
1445a36c61f9SKrishna Gudipati 	switch (event) {
1446a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_ERROR:
1447a36c61f9SKrishna Gudipati 		/*
1448a36c61f9SKrishna Gudipati 		 * if max retries have not been reached, start timer for a
1449a36c61f9SKrishna Gudipati 		 * delayed retry
1450a36c61f9SKrishna Gudipati 		 */
1451a36c61f9SKrishna Gudipati 		if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1452a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1453a36c61f9SKrishna Gudipati 					bfa_fcs_lport_fdmi_sm_rprt_retry);
1454a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1455a36c61f9SKrishna Gudipati 					    &fdmi->timer,
1456a36c61f9SKrishna Gudipati 					    bfa_fcs_lport_fdmi_timeout, fdmi,
1457a36c61f9SKrishna Gudipati 					    BFA_FCS_RETRY_TIMEOUT);
14587725ccfdSJing Huang 
14597725ccfdSJing Huang 		} else {
1460a36c61f9SKrishna Gudipati 			/*
1461a36c61f9SKrishna Gudipati 			 * set state to offline
1462a36c61f9SKrishna Gudipati 			 */
1463a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1464a36c61f9SKrishna Gudipati 			fdmi->retry_cnt = 0;
14657725ccfdSJing Huang 		}
1466a36c61f9SKrishna Gudipati 		break;
1467a36c61f9SKrishna Gudipati 
1468a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_OK:
1469a36c61f9SKrishna Gudipati 		fdmi->retry_cnt = 0;
1470a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1471a36c61f9SKrishna Gudipati 		break;
1472a36c61f9SKrishna Gudipati 
1473a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1474a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(fdmi->fcxp);
1475a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1476a36c61f9SKrishna Gudipati 		break;
1477a36c61f9SKrishna Gudipati 
1478a36c61f9SKrishna Gudipati 	default:
1479a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1480a36c61f9SKrishna Gudipati 	}
1481a36c61f9SKrishna Gudipati }
1482a36c61f9SKrishna Gudipati 
1483a36c61f9SKrishna Gudipati static void
1484a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1485a36c61f9SKrishna Gudipati 				enum port_fdmi_event event)
1486a36c61f9SKrishna Gudipati {
1487a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1488a36c61f9SKrishna Gudipati 
1489a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1490a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1491a36c61f9SKrishna Gudipati 
1492a36c61f9SKrishna Gudipati 	switch (event) {
1493a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_TIMEOUT:
1494a36c61f9SKrishna Gudipati 		/*
1495a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
1496a36c61f9SKrishna Gudipati 		 */
1497a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt);
1498a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1499a36c61f9SKrishna Gudipati 		break;
1500a36c61f9SKrishna Gudipati 
1501a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1502a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1503a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fdmi->timer);
1504a36c61f9SKrishna Gudipati 		break;
1505a36c61f9SKrishna Gudipati 
1506a36c61f9SKrishna Gudipati 	default:
1507a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1508a36c61f9SKrishna Gudipati 	}
1509a36c61f9SKrishna Gudipati }
1510a36c61f9SKrishna Gudipati 
1511a36c61f9SKrishna Gudipati /*
1512a36c61f9SKrishna Gudipati  * Register Port Attributes
1513a36c61f9SKrishna Gudipati  */
1514a36c61f9SKrishna Gudipati static void
1515a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1516a36c61f9SKrishna Gudipati 				 enum port_fdmi_event event)
1517a36c61f9SKrishna Gudipati {
1518a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1519a36c61f9SKrishna Gudipati 
1520a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1521a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1522a36c61f9SKrishna Gudipati 
1523a36c61f9SKrishna Gudipati 	switch (event) {
1524a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RPA_SENT:
1525a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa);
1526a36c61f9SKrishna Gudipati 		break;
1527a36c61f9SKrishna Gudipati 
1528a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1529a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1530a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1531a36c61f9SKrishna Gudipati 					   &fdmi->fcxp_wqe);
1532a36c61f9SKrishna Gudipati 		break;
1533a36c61f9SKrishna Gudipati 
1534a36c61f9SKrishna Gudipati 	default:
1535a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1536a36c61f9SKrishna Gudipati 	}
1537a36c61f9SKrishna Gudipati }
1538a36c61f9SKrishna Gudipati 
1539a36c61f9SKrishna Gudipati static void
1540a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1541a36c61f9SKrishna Gudipati 			enum port_fdmi_event event)
1542a36c61f9SKrishna Gudipati {
1543a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1544a36c61f9SKrishna Gudipati 
1545a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1546a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1547a36c61f9SKrishna Gudipati 
1548a36c61f9SKrishna Gudipati 	switch (event) {
1549a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_ERROR:
1550a36c61f9SKrishna Gudipati 		/*
1551a36c61f9SKrishna Gudipati 		 * if max retries have not been reached, start timer for a
1552a36c61f9SKrishna Gudipati 		 * delayed retry
1553a36c61f9SKrishna Gudipati 		 */
1554a36c61f9SKrishna Gudipati 		if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1555a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry);
1556a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1557a36c61f9SKrishna Gudipati 					    &fdmi->timer,
1558a36c61f9SKrishna Gudipati 					    bfa_fcs_lport_fdmi_timeout, fdmi,
1559a36c61f9SKrishna Gudipati 					    BFA_FCS_RETRY_TIMEOUT);
1560a36c61f9SKrishna Gudipati 		} else {
1561a36c61f9SKrishna Gudipati 			/*
1562a36c61f9SKrishna Gudipati 			 * set state to offline
1563a36c61f9SKrishna Gudipati 			 */
1564a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1565a36c61f9SKrishna Gudipati 			fdmi->retry_cnt = 0;
1566a36c61f9SKrishna Gudipati 		}
1567a36c61f9SKrishna Gudipati 		break;
1568a36c61f9SKrishna Gudipati 
1569a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_OK:
1570a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1571a36c61f9SKrishna Gudipati 		fdmi->retry_cnt = 0;
1572a36c61f9SKrishna Gudipati 		break;
1573a36c61f9SKrishna Gudipati 
1574a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1575a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(fdmi->fcxp);
1576a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1577a36c61f9SKrishna Gudipati 		break;
1578a36c61f9SKrishna Gudipati 
1579a36c61f9SKrishna Gudipati 	default:
1580a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1581a36c61f9SKrishna Gudipati 	}
1582a36c61f9SKrishna Gudipati }
1583a36c61f9SKrishna Gudipati 
1584a36c61f9SKrishna Gudipati static void
1585a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1586a36c61f9SKrishna Gudipati 			       enum port_fdmi_event event)
1587a36c61f9SKrishna Gudipati {
1588a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1589a36c61f9SKrishna Gudipati 
1590a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1591a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1592a36c61f9SKrishna Gudipati 
1593a36c61f9SKrishna Gudipati 	switch (event) {
1594a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_TIMEOUT:
1595a36c61f9SKrishna Gudipati 		/*
1596a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
1597a36c61f9SKrishna Gudipati 		 */
1598a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1599a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1600a36c61f9SKrishna Gudipati 		break;
1601a36c61f9SKrishna Gudipati 
1602a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1603a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1604a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fdmi->timer);
1605a36c61f9SKrishna Gudipati 		break;
1606a36c61f9SKrishna Gudipati 
1607a36c61f9SKrishna Gudipati 	default:
1608a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1609a36c61f9SKrishna Gudipati 	}
1610a36c61f9SKrishna Gudipati }
1611a36c61f9SKrishna Gudipati 
1612a36c61f9SKrishna Gudipati static void
1613a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1614a36c61f9SKrishna Gudipati 				enum port_fdmi_event event)
1615a36c61f9SKrishna Gudipati {
1616a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1617a36c61f9SKrishna Gudipati 
1618a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1619a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1620a36c61f9SKrishna Gudipati 
1621a36c61f9SKrishna Gudipati 	switch (event) {
1622a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1623a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1624a36c61f9SKrishna Gudipati 		break;
1625a36c61f9SKrishna Gudipati 
1626a36c61f9SKrishna Gudipati 	default:
1627a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1628a36c61f9SKrishna Gudipati 	}
1629a36c61f9SKrishna Gudipati }
16305fbe25c7SJing Huang /*
1631a36c61f9SKrishna Gudipati  *  FDMI is disabled state.
1632a36c61f9SKrishna Gudipati  */
1633a36c61f9SKrishna Gudipati static void
1634a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi,
1635a36c61f9SKrishna Gudipati 			     enum port_fdmi_event event)
1636a36c61f9SKrishna Gudipati {
1637a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1638a36c61f9SKrishna Gudipati 
1639a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1640a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1641a36c61f9SKrishna Gudipati 
1642a36c61f9SKrishna Gudipati 	/* No op State. It can only be enabled at Driver Init. */
1643a36c61f9SKrishna Gudipati }
1644a36c61f9SKrishna Gudipati 
16455fbe25c7SJing Huang /*
1646a36c61f9SKrishna Gudipati *  RHBA : Register HBA Attributes.
1647a36c61f9SKrishna Gudipati  */
1648a36c61f9SKrishna Gudipati static void
1649a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1650a36c61f9SKrishna Gudipati {
1651a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1652a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1653a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
1654a36c61f9SKrishna Gudipati 	int             len, attr_len;
1655a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1656a36c61f9SKrishna Gudipati 	u8        *pyld;
1657a36c61f9SKrishna Gudipati 
1658a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1659a36c61f9SKrishna Gudipati 
1660a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1661a36c61f9SKrishna Gudipati 	if (!fcxp) {
1662a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1663a36c61f9SKrishna Gudipati 					bfa_fcs_lport_fdmi_send_rhba, fdmi);
1664a36c61f9SKrishna Gudipati 		return;
1665a36c61f9SKrishna Gudipati 	}
1666a36c61f9SKrishna Gudipati 	fdmi->fcxp = fcxp;
1667a36c61f9SKrishna Gudipati 
1668a36c61f9SKrishna Gudipati 	pyld = bfa_fcxp_get_reqbuf(fcxp);
16696a18b167SJing Huang 	memset(pyld, 0, FC_MAX_PDUSZ);
1670a36c61f9SKrishna Gudipati 
1671a36c61f9SKrishna Gudipati 	len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
1672a36c61f9SKrishna Gudipati 				   FDMI_RHBA);
1673a36c61f9SKrishna Gudipati 
1674a36c61f9SKrishna Gudipati 	attr_len =
1675a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi,
1676a36c61f9SKrishna Gudipati 					  (u8 *) ((struct ct_hdr_s *) pyld
1677a36c61f9SKrishna Gudipati 						       + 1));
1678a36c61f9SKrishna Gudipati 
1679a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1680a36c61f9SKrishna Gudipati 			  FC_CLASS_3, (len + attr_len), &fchs,
1681a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi,
1682a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
1683a36c61f9SKrishna Gudipati 
1684a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
1685a36c61f9SKrishna Gudipati }
1686a36c61f9SKrishna Gudipati 
1687a36c61f9SKrishna Gudipati static          u16
1688a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
1689a36c61f9SKrishna Gudipati {
1690a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1691a36c61f9SKrishna Gudipati 	struct bfa_fcs_fdmi_hba_attr_s hba_attr;
1692a36c61f9SKrishna Gudipati 	struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr;
1693a36c61f9SKrishna Gudipati 	struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld;
1694a36c61f9SKrishna Gudipati 	struct fdmi_attr_s *attr;
1695a36c61f9SKrishna Gudipati 	u8        *curr_ptr;
1696a36c61f9SKrishna Gudipati 	u16        len, count;
169750444a34SMaggie 	u16	templen;
1698a36c61f9SKrishna Gudipati 
1699a36c61f9SKrishna Gudipati 	/*
1700a36c61f9SKrishna Gudipati 	 * get hba attributes
1701a36c61f9SKrishna Gudipati 	 */
1702a36c61f9SKrishna Gudipati 	bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
1703a36c61f9SKrishna Gudipati 
1704a36c61f9SKrishna Gudipati 	rhba->hba_id = bfa_fcs_lport_get_pwwn(port);
1705ba816ea8SJing Huang 	rhba->port_list.num_ports = cpu_to_be32(1);
1706a36c61f9SKrishna Gudipati 	rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port);
1707a36c61f9SKrishna Gudipati 
1708a36c61f9SKrishna Gudipati 	len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
1709a36c61f9SKrishna Gudipati 
1710a36c61f9SKrishna Gudipati 	count = 0;
1711a36c61f9SKrishna Gudipati 	len += sizeof(rhba->hba_attr_blk.attr_count);
1712a36c61f9SKrishna Gudipati 
1713a36c61f9SKrishna Gudipati 	/*
1714a36c61f9SKrishna Gudipati 	 * fill out the invididual entries of the HBA attrib Block
1715a36c61f9SKrishna Gudipati 	 */
1716a36c61f9SKrishna Gudipati 	curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
1717a36c61f9SKrishna Gudipati 
1718a36c61f9SKrishna Gudipati 	/*
1719a36c61f9SKrishna Gudipati 	 * Node Name
1720a36c61f9SKrishna Gudipati 	 */
1721a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1722ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME);
172350444a34SMaggie 	templen = sizeof(wwn_t);
172450444a34SMaggie 	memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen);
172550444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
172650444a34SMaggie 	len += templen;
1727a36c61f9SKrishna Gudipati 	count++;
172850444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
172950444a34SMaggie 			     sizeof(templen));
1730a36c61f9SKrishna Gudipati 
1731a36c61f9SKrishna Gudipati 	/*
1732a36c61f9SKrishna Gudipati 	 * Manufacturer
1733a36c61f9SKrishna Gudipati 	 */
1734a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1735ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER);
173650444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->manufacturer);
173750444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->manufacturer, templen);
173850444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
173950444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
174050444a34SMaggie 	len += templen;
1741a36c61f9SKrishna Gudipati 	count++;
174250444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
174350444a34SMaggie 			     sizeof(templen));
1744a36c61f9SKrishna Gudipati 
1745a36c61f9SKrishna Gudipati 	/*
1746a36c61f9SKrishna Gudipati 	 * Serial Number
1747a36c61f9SKrishna Gudipati 	 */
1748a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1749ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM);
175050444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->serial_num);
175150444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->serial_num, templen);
175250444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
175350444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
175450444a34SMaggie 	len += templen;
1755a36c61f9SKrishna Gudipati 	count++;
175650444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
175750444a34SMaggie 			     sizeof(templen));
1758a36c61f9SKrishna Gudipati 
1759a36c61f9SKrishna Gudipati 	/*
1760a36c61f9SKrishna Gudipati 	 * Model
1761a36c61f9SKrishna Gudipati 	 */
1762a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1763ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL);
176450444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->model);
176550444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->model, templen);
176650444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
176750444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
176850444a34SMaggie 	len += templen;
1769a36c61f9SKrishna Gudipati 	count++;
177050444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
177150444a34SMaggie 			     sizeof(templen));
1772a36c61f9SKrishna Gudipati 
1773a36c61f9SKrishna Gudipati 	/*
1774a36c61f9SKrishna Gudipati 	 * Model Desc
1775a36c61f9SKrishna Gudipati 	 */
1776a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1777ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC);
177850444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->model_desc);
177950444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->model_desc, templen);
178050444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
178150444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
178250444a34SMaggie 	len += templen;
1783a36c61f9SKrishna Gudipati 	count++;
178450444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
178550444a34SMaggie 			     sizeof(templen));
1786a36c61f9SKrishna Gudipati 
1787a36c61f9SKrishna Gudipati 	/*
1788a36c61f9SKrishna Gudipati 	 * H/W Version
1789a36c61f9SKrishna Gudipati 	 */
1790a36c61f9SKrishna Gudipati 	if (fcs_hba_attr->hw_version[0] != '\0') {
1791a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
1792ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION);
179350444a34SMaggie 		templen = (u16) strlen(fcs_hba_attr->hw_version);
179450444a34SMaggie 		memcpy(attr->value, fcs_hba_attr->hw_version, templen);
179550444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
179650444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
179750444a34SMaggie 		len += templen;
1798a36c61f9SKrishna Gudipati 		count++;
179950444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
180050444a34SMaggie 					 sizeof(templen));
1801a36c61f9SKrishna Gudipati 	}
1802a36c61f9SKrishna Gudipati 
1803a36c61f9SKrishna Gudipati 	/*
1804a36c61f9SKrishna Gudipati 	 * Driver Version
1805a36c61f9SKrishna Gudipati 	 */
1806a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1807ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION);
180850444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->driver_version);
180950444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->driver_version, templen);
181050444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
181150444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1812dd5aaf45SKrishna Gudipati 	len += templen;
1813a36c61f9SKrishna Gudipati 	count++;
181450444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
181550444a34SMaggie 			     sizeof(templen));
1816a36c61f9SKrishna Gudipati 
1817a36c61f9SKrishna Gudipati 	/*
1818a36c61f9SKrishna Gudipati 	 * Option Rom Version
1819a36c61f9SKrishna Gudipati 	 */
1820a36c61f9SKrishna Gudipati 	if (fcs_hba_attr->option_rom_ver[0] != '\0') {
1821a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
1822ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION);
182350444a34SMaggie 		templen = (u16) strlen(fcs_hba_attr->option_rom_ver);
182450444a34SMaggie 		memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen);
182550444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
182650444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
182750444a34SMaggie 		len += templen;
1828a36c61f9SKrishna Gudipati 		count++;
182950444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
183050444a34SMaggie 					 sizeof(templen));
1831a36c61f9SKrishna Gudipati 	}
1832a36c61f9SKrishna Gudipati 
1833a36c61f9SKrishna Gudipati 	/*
1834a36c61f9SKrishna Gudipati 	 * f/w Version = driver version
1835a36c61f9SKrishna Gudipati 	 */
1836a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1837ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION);
183850444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->driver_version);
183950444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->driver_version, templen);
184050444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
184150444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
184250444a34SMaggie 	len += templen;
1843a36c61f9SKrishna Gudipati 	count++;
184450444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
184550444a34SMaggie 			     sizeof(templen));
1846a36c61f9SKrishna Gudipati 
1847a36c61f9SKrishna Gudipati 	/*
1848a36c61f9SKrishna Gudipati 	 * OS Name
1849a36c61f9SKrishna Gudipati 	 */
1850a36c61f9SKrishna Gudipati 	if (fcs_hba_attr->os_name[0] != '\0') {
1851a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
1852ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME);
185350444a34SMaggie 		templen = (u16) strlen(fcs_hba_attr->os_name);
185450444a34SMaggie 		memcpy(attr->value, fcs_hba_attr->os_name, templen);
185550444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
185650444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
185750444a34SMaggie 		len += templen;
1858a36c61f9SKrishna Gudipati 		count++;
185950444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
186050444a34SMaggie 					sizeof(templen));
1861a36c61f9SKrishna Gudipati 	}
1862a36c61f9SKrishna Gudipati 
1863a36c61f9SKrishna Gudipati 	/*
1864a36c61f9SKrishna Gudipati 	 * MAX_CT_PAYLOAD
1865a36c61f9SKrishna Gudipati 	 */
1866a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1867ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT);
186850444a34SMaggie 	templen = sizeof(fcs_hba_attr->max_ct_pyld);
186950444a34SMaggie 	memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen);
187050444a34SMaggie 	len += templen;
1871a36c61f9SKrishna Gudipati 	count++;
187250444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
187350444a34SMaggie 			     sizeof(templen));
1874a36c61f9SKrishna Gudipati 
1875a36c61f9SKrishna Gudipati 	/*
1876a36c61f9SKrishna Gudipati 	 * Update size of payload
1877a36c61f9SKrishna Gudipati 	 */
18785fbe25c7SJing Huang 	len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
1879a36c61f9SKrishna Gudipati 
1880ba816ea8SJing Huang 	rhba->hba_attr_blk.attr_count = cpu_to_be32(count);
1881a36c61f9SKrishna Gudipati 	return len;
1882a36c61f9SKrishna Gudipati }
1883a36c61f9SKrishna Gudipati 
1884a36c61f9SKrishna Gudipati static void
1885a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
1886a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
1887a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
1888a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
1889a36c61f9SKrishna Gudipati {
1890a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi =
1891a36c61f9SKrishna Gudipati 				(struct bfa_fcs_lport_fdmi_s *) cbarg;
1892a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1893a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
1894a36c61f9SKrishna Gudipati 
1895a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1896a36c61f9SKrishna Gudipati 
1897a36c61f9SKrishna Gudipati 	/*
1898a36c61f9SKrishna Gudipati 	 * Sanity Checks
1899a36c61f9SKrishna Gudipati 	 */
1900a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
1901a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
1902a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1903a36c61f9SKrishna Gudipati 		return;
1904a36c61f9SKrishna Gudipati 	}
1905a36c61f9SKrishna Gudipati 
1906a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1907ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1908a36c61f9SKrishna Gudipati 
1909a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1910a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
1911a36c61f9SKrishna Gudipati 		return;
1912a36c61f9SKrishna Gudipati 	}
1913a36c61f9SKrishna Gudipati 
1914a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
1915a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
1916a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1917a36c61f9SKrishna Gudipati }
1918a36c61f9SKrishna Gudipati 
19195fbe25c7SJing Huang /*
1920a36c61f9SKrishna Gudipati *  RPRT : Register Port
1921a36c61f9SKrishna Gudipati  */
1922a36c61f9SKrishna Gudipati static void
1923a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1924a36c61f9SKrishna Gudipati {
1925a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1926a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1927a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
1928a36c61f9SKrishna Gudipati 	u16        len, attr_len;
1929a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1930a36c61f9SKrishna Gudipati 	u8        *pyld;
1931a36c61f9SKrishna Gudipati 
1932a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1933a36c61f9SKrishna Gudipati 
1934a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1935a36c61f9SKrishna Gudipati 	if (!fcxp) {
1936a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1937a36c61f9SKrishna Gudipati 					bfa_fcs_lport_fdmi_send_rprt, fdmi);
1938a36c61f9SKrishna Gudipati 		return;
1939a36c61f9SKrishna Gudipati 	}
1940a36c61f9SKrishna Gudipati 	fdmi->fcxp = fcxp;
1941a36c61f9SKrishna Gudipati 
1942a36c61f9SKrishna Gudipati 	pyld = bfa_fcxp_get_reqbuf(fcxp);
19436a18b167SJing Huang 	memset(pyld, 0, FC_MAX_PDUSZ);
1944a36c61f9SKrishna Gudipati 
1945a36c61f9SKrishna Gudipati 	len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
1946a36c61f9SKrishna Gudipati 				   FDMI_RPRT);
1947a36c61f9SKrishna Gudipati 
1948a36c61f9SKrishna Gudipati 	attr_len =
1949a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi,
1950a36c61f9SKrishna Gudipati 					  (u8 *) ((struct ct_hdr_s *) pyld
1951a36c61f9SKrishna Gudipati 						       + 1));
1952a36c61f9SKrishna Gudipati 
1953a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1954a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len + attr_len, &fchs,
1955a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi,
1956a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
1957a36c61f9SKrishna Gudipati 
1958a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
1959a36c61f9SKrishna Gudipati }
1960a36c61f9SKrishna Gudipati 
19615fbe25c7SJing Huang /*
1962a36c61f9SKrishna Gudipati  * This routine builds Port Attribute Block that used in RPA, RPRT commands.
1963a36c61f9SKrishna Gudipati  */
1964a36c61f9SKrishna Gudipati static          u16
1965a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
1966a36c61f9SKrishna Gudipati 				       u8 *pyld)
1967a36c61f9SKrishna Gudipati {
1968a36c61f9SKrishna Gudipati 	struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
1969a36c61f9SKrishna Gudipati 	struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld;
1970a36c61f9SKrishna Gudipati 	struct fdmi_attr_s *attr;
1971a36c61f9SKrishna Gudipati 	u8        *curr_ptr;
1972a36c61f9SKrishna Gudipati 	u16        len;
1973a36c61f9SKrishna Gudipati 	u8	count = 0;
197450444a34SMaggie 	u16	templen;
1975a36c61f9SKrishna Gudipati 
1976a36c61f9SKrishna Gudipati 	/*
1977a36c61f9SKrishna Gudipati 	 * get port attributes
1978a36c61f9SKrishna Gudipati 	 */
1979a36c61f9SKrishna Gudipati 	bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
1980a36c61f9SKrishna Gudipati 
1981a36c61f9SKrishna Gudipati 	len = sizeof(port_attrib->attr_count);
1982a36c61f9SKrishna Gudipati 
1983a36c61f9SKrishna Gudipati 	/*
1984a36c61f9SKrishna Gudipati 	 * fill out the invididual entries
1985a36c61f9SKrishna Gudipati 	 */
1986a36c61f9SKrishna Gudipati 	curr_ptr = (u8 *) &port_attrib->port_attr;
1987a36c61f9SKrishna Gudipati 
1988a36c61f9SKrishna Gudipati 	/*
1989a36c61f9SKrishna Gudipati 	 * FC4 Types
1990a36c61f9SKrishna Gudipati 	 */
1991a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1992ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES);
199350444a34SMaggie 	templen = sizeof(fcs_port_attr.supp_fc4_types);
199450444a34SMaggie 	memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen);
199550444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
199650444a34SMaggie 	len += templen;
1997a36c61f9SKrishna Gudipati 	++count;
1998a36c61f9SKrishna Gudipati 	attr->len =
199950444a34SMaggie 		cpu_to_be16(templen + sizeof(attr->type) +
200050444a34SMaggie 			     sizeof(templen));
2001a36c61f9SKrishna Gudipati 
2002a36c61f9SKrishna Gudipati 	/*
2003a36c61f9SKrishna Gudipati 	 * Supported Speed
2004a36c61f9SKrishna Gudipati 	 */
2005a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2006ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED);
200750444a34SMaggie 	templen = sizeof(fcs_port_attr.supp_speed);
200850444a34SMaggie 	memcpy(attr->value, &fcs_port_attr.supp_speed, templen);
200950444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
201050444a34SMaggie 	len += templen;
2011a36c61f9SKrishna Gudipati 	++count;
2012a36c61f9SKrishna Gudipati 	attr->len =
201350444a34SMaggie 		cpu_to_be16(templen + sizeof(attr->type) +
201450444a34SMaggie 			     sizeof(templen));
2015a36c61f9SKrishna Gudipati 
2016a36c61f9SKrishna Gudipati 	/*
2017a36c61f9SKrishna Gudipati 	 * current Port Speed
2018a36c61f9SKrishna Gudipati 	 */
2019a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2020ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED);
202150444a34SMaggie 	templen = sizeof(fcs_port_attr.curr_speed);
202250444a34SMaggie 	memcpy(attr->value, &fcs_port_attr.curr_speed, templen);
202350444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
202450444a34SMaggie 	len += templen;
2025a36c61f9SKrishna Gudipati 	++count;
202650444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
202750444a34SMaggie 			     sizeof(templen));
2028a36c61f9SKrishna Gudipati 
2029a36c61f9SKrishna Gudipati 	/*
2030a36c61f9SKrishna Gudipati 	 * max frame size
2031a36c61f9SKrishna Gudipati 	 */
2032a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2033ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE);
203450444a34SMaggie 	templen = sizeof(fcs_port_attr.max_frm_size);
203550444a34SMaggie 	memcpy(attr->value, &fcs_port_attr.max_frm_size, templen);
203650444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
203750444a34SMaggie 	len += templen;
2038a36c61f9SKrishna Gudipati 	++count;
203950444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
204050444a34SMaggie 			     sizeof(templen));
2041a36c61f9SKrishna Gudipati 
2042a36c61f9SKrishna Gudipati 	/*
2043a36c61f9SKrishna Gudipati 	 * OS Device Name
2044a36c61f9SKrishna Gudipati 	 */
2045a36c61f9SKrishna Gudipati 	if (fcs_port_attr.os_device_name[0] != '\0') {
2046a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
2047ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME);
204850444a34SMaggie 		templen = (u16) strlen(fcs_port_attr.os_device_name);
204950444a34SMaggie 		memcpy(attr->value, fcs_port_attr.os_device_name, templen);
205050444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
205150444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
205250444a34SMaggie 		len += templen;
2053a36c61f9SKrishna Gudipati 		++count;
205450444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
205550444a34SMaggie 					sizeof(templen));
2056a36c61f9SKrishna Gudipati 	}
2057a36c61f9SKrishna Gudipati 	/*
2058a36c61f9SKrishna Gudipati 	 * Host Name
2059a36c61f9SKrishna Gudipati 	 */
2060a36c61f9SKrishna Gudipati 	if (fcs_port_attr.host_name[0] != '\0') {
2061a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
2062ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME);
206350444a34SMaggie 		templen = (u16) strlen(fcs_port_attr.host_name);
206450444a34SMaggie 		memcpy(attr->value, fcs_port_attr.host_name, templen);
206550444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
206650444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
206750444a34SMaggie 		len += templen;
2068a36c61f9SKrishna Gudipati 		++count;
206950444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
207050444a34SMaggie 				sizeof(templen));
2071a36c61f9SKrishna Gudipati 	}
2072a36c61f9SKrishna Gudipati 
2073a36c61f9SKrishna Gudipati 	/*
2074a36c61f9SKrishna Gudipati 	 * Update size of payload
2075a36c61f9SKrishna Gudipati 	 */
2076ba816ea8SJing Huang 	port_attrib->attr_count = cpu_to_be32(count);
20775fbe25c7SJing Huang 	len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
2078a36c61f9SKrishna Gudipati 	return len;
2079a36c61f9SKrishna Gudipati }
2080a36c61f9SKrishna Gudipati 
2081a36c61f9SKrishna Gudipati static          u16
2082a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2083a36c61f9SKrishna Gudipati {
2084a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2085a36c61f9SKrishna Gudipati 	struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld;
2086a36c61f9SKrishna Gudipati 	u16        len;
2087a36c61f9SKrishna Gudipati 
2088a36c61f9SKrishna Gudipati 	rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs));
2089a36c61f9SKrishna Gudipati 	rprt->port_name = bfa_fcs_lport_get_pwwn(port);
2090a36c61f9SKrishna Gudipati 
2091a36c61f9SKrishna Gudipati 	len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2092a36c61f9SKrishna Gudipati 				(u8 *) &rprt->port_attr_blk);
2093a36c61f9SKrishna Gudipati 
2094a36c61f9SKrishna Gudipati 	len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
2095a36c61f9SKrishna Gudipati 
2096a36c61f9SKrishna Gudipati 	return len;
2097a36c61f9SKrishna Gudipati }
2098a36c61f9SKrishna Gudipati 
2099a36c61f9SKrishna Gudipati static void
2100a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2101a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
2102a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
2103a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
2104a36c61f9SKrishna Gudipati {
2105a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi =
2106a36c61f9SKrishna Gudipati 			(struct bfa_fcs_lport_fdmi_s *) cbarg;
2107a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2108a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
2109a36c61f9SKrishna Gudipati 
2110a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2111a36c61f9SKrishna Gudipati 
2112a36c61f9SKrishna Gudipati 	/*
2113a36c61f9SKrishna Gudipati 	 * Sanity Checks
2114a36c61f9SKrishna Gudipati 	 */
2115a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2116a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
2117a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2118a36c61f9SKrishna Gudipati 		return;
2119a36c61f9SKrishna Gudipati 	}
2120a36c61f9SKrishna Gudipati 
2121a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2122ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2123a36c61f9SKrishna Gudipati 
2124a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2125a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2126a36c61f9SKrishna Gudipati 		return;
2127a36c61f9SKrishna Gudipati 	}
2128a36c61f9SKrishna Gudipati 
2129a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
2130a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
2131a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2132a36c61f9SKrishna Gudipati }
2133a36c61f9SKrishna Gudipati 
21345fbe25c7SJing Huang /*
2135a36c61f9SKrishna Gudipati *  RPA : Register Port Attributes.
2136a36c61f9SKrishna Gudipati  */
2137a36c61f9SKrishna Gudipati static void
2138a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2139a36c61f9SKrishna Gudipati {
2140a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
2141a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2142a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
2143a36c61f9SKrishna Gudipati 	u16        len, attr_len;
2144a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2145a36c61f9SKrishna Gudipati 	u8        *pyld;
2146a36c61f9SKrishna Gudipati 
2147a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2148a36c61f9SKrishna Gudipati 
2149a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2150a36c61f9SKrishna Gudipati 	if (!fcxp) {
2151a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2152a36c61f9SKrishna Gudipati 					bfa_fcs_lport_fdmi_send_rpa, fdmi);
2153a36c61f9SKrishna Gudipati 		return;
2154a36c61f9SKrishna Gudipati 	}
2155a36c61f9SKrishna Gudipati 	fdmi->fcxp = fcxp;
2156a36c61f9SKrishna Gudipati 
2157a36c61f9SKrishna Gudipati 	pyld = bfa_fcxp_get_reqbuf(fcxp);
21586a18b167SJing Huang 	memset(pyld, 0, FC_MAX_PDUSZ);
2159a36c61f9SKrishna Gudipati 
2160a36c61f9SKrishna Gudipati 	len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2161a36c61f9SKrishna Gudipati 				   FDMI_RPA);
2162a36c61f9SKrishna Gudipati 
21635fbe25c7SJing Huang 	attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi,
21645fbe25c7SJing Huang 				(u8 *) ((struct ct_hdr_s *) pyld + 1));
2165a36c61f9SKrishna Gudipati 
2166a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2167a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len + attr_len, &fchs,
2168a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi,
2169a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
2170a36c61f9SKrishna Gudipati 
2171a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
2172a36c61f9SKrishna Gudipati }
2173a36c61f9SKrishna Gudipati 
2174a36c61f9SKrishna Gudipati static          u16
2175a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2176a36c61f9SKrishna Gudipati {
2177a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2178a36c61f9SKrishna Gudipati 	struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld;
2179a36c61f9SKrishna Gudipati 	u16        len;
2180a36c61f9SKrishna Gudipati 
2181a36c61f9SKrishna Gudipati 	rpa->port_name = bfa_fcs_lport_get_pwwn(port);
2182a36c61f9SKrishna Gudipati 
2183a36c61f9SKrishna Gudipati 	len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2184a36c61f9SKrishna Gudipati 				(u8 *) &rpa->port_attr_blk);
2185a36c61f9SKrishna Gudipati 
2186a36c61f9SKrishna Gudipati 	len += sizeof(rpa->port_name);
2187a36c61f9SKrishna Gudipati 
2188a36c61f9SKrishna Gudipati 	return len;
2189a36c61f9SKrishna Gudipati }
2190a36c61f9SKrishna Gudipati 
2191a36c61f9SKrishna Gudipati static void
2192a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2193a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
2194a36c61f9SKrishna Gudipati 			u32 resid_len, struct fchs_s *rsp_fchs)
2195a36c61f9SKrishna Gudipati {
2196a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi =
2197a36c61f9SKrishna Gudipati 				(struct bfa_fcs_lport_fdmi_s *) cbarg;
2198a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2199a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
2200a36c61f9SKrishna Gudipati 
2201a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2202a36c61f9SKrishna Gudipati 
2203a36c61f9SKrishna Gudipati 	/*
2204a36c61f9SKrishna Gudipati 	 * Sanity Checks
2205a36c61f9SKrishna Gudipati 	 */
2206a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2207a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
2208a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2209a36c61f9SKrishna Gudipati 		return;
2210a36c61f9SKrishna Gudipati 	}
2211a36c61f9SKrishna Gudipati 
2212a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2213ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2214a36c61f9SKrishna Gudipati 
2215a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2216a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2217a36c61f9SKrishna Gudipati 		return;
2218a36c61f9SKrishna Gudipati 	}
2219a36c61f9SKrishna Gudipati 
2220a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
2221a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
2222a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2223a36c61f9SKrishna Gudipati }
2224a36c61f9SKrishna Gudipati 
2225a36c61f9SKrishna Gudipati static void
2226a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout(void *arg)
2227a36c61f9SKrishna Gudipati {
2228a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg;
2229a36c61f9SKrishna Gudipati 
2230a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
2231a36c61f9SKrishna Gudipati }
2232a36c61f9SKrishna Gudipati 
223352f94b6fSMaggie static void
2234a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2235a36c61f9SKrishna Gudipati 			 struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
2236a36c61f9SKrishna Gudipati {
2237a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2238a36c61f9SKrishna Gudipati 	struct bfa_fcs_driver_info_s  *driver_info = &port->fcs->driver_info;
2239a36c61f9SKrishna Gudipati 
22406a18b167SJing Huang 	memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
2241a36c61f9SKrishna Gudipati 
2242a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
2243a36c61f9SKrishna Gudipati 					hba_attr->manufacturer);
2244a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
2245a36c61f9SKrishna Gudipati 					hba_attr->serial_num);
2246a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2247a36c61f9SKrishna Gudipati 					hba_attr->model);
2248a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2249a36c61f9SKrishna Gudipati 					hba_attr->model_desc);
2250a36c61f9SKrishna Gudipati 	bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc,
2251a36c61f9SKrishna Gudipati 					hba_attr->hw_version);
2252a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
2253a36c61f9SKrishna Gudipati 					hba_attr->option_rom_ver);
2254a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc,
2255a36c61f9SKrishna Gudipati 					hba_attr->fw_version);
2256a36c61f9SKrishna Gudipati 
2257a36c61f9SKrishna Gudipati 	strncpy(hba_attr->driver_version, (char *)driver_info->version,
2258a36c61f9SKrishna Gudipati 		sizeof(hba_attr->driver_version));
2259a36c61f9SKrishna Gudipati 
2260a36c61f9SKrishna Gudipati 	strncpy(hba_attr->os_name, driver_info->host_os_name,
2261a36c61f9SKrishna Gudipati 		sizeof(hba_attr->os_name));
2262a36c61f9SKrishna Gudipati 
2263a36c61f9SKrishna Gudipati 	/*
2264a36c61f9SKrishna Gudipati 	 * If there is a patch level, append it
2265a36c61f9SKrishna Gudipati 	 * to the os name along with a separator
2266a36c61f9SKrishna Gudipati 	 */
2267a36c61f9SKrishna Gudipati 	if (driver_info->host_os_patch[0] != '\0') {
2268a36c61f9SKrishna Gudipati 		strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
2269a36c61f9SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
2270a36c61f9SKrishna Gudipati 		strncat(hba_attr->os_name, driver_info->host_os_patch,
2271a36c61f9SKrishna Gudipati 				sizeof(driver_info->host_os_patch));
2272a36c61f9SKrishna Gudipati 	}
2273a36c61f9SKrishna Gudipati 
2274ba816ea8SJing Huang 	hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ);
2275a36c61f9SKrishna Gudipati }
2276a36c61f9SKrishna Gudipati 
227752f94b6fSMaggie static void
2278a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2279a36c61f9SKrishna Gudipati 			  struct bfa_fcs_fdmi_port_attr_s *port_attr)
2280a36c61f9SKrishna Gudipati {
2281a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2282a36c61f9SKrishna Gudipati 	struct bfa_fcs_driver_info_s  *driver_info = &port->fcs->driver_info;
2283a36c61f9SKrishna Gudipati 	struct bfa_port_attr_s pport_attr;
2284a36c61f9SKrishna Gudipati 
22856a18b167SJing Huang 	memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
2286a36c61f9SKrishna Gudipati 
2287a36c61f9SKrishna Gudipati 	/*
2288a36c61f9SKrishna Gudipati 	 * get pport attributes from hal
2289a36c61f9SKrishna Gudipati 	 */
2290a36c61f9SKrishna Gudipati 	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2291a36c61f9SKrishna Gudipati 
2292a36c61f9SKrishna Gudipati 	/*
2293a36c61f9SKrishna Gudipati 	 * get FC4 type Bitmask
2294a36c61f9SKrishna Gudipati 	 */
2295a36c61f9SKrishna Gudipati 	fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
2296a36c61f9SKrishna Gudipati 
2297a36c61f9SKrishna Gudipati 	/*
2298a36c61f9SKrishna Gudipati 	 * Supported Speeds
2299a36c61f9SKrishna Gudipati 	 */
2300d7be54ccSKrishna Gudipati 	switch (pport_attr.speed_supported) {
2301d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_16GBPS:
2302d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2303d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G);
2304d7be54ccSKrishna Gudipati 		break;
2305d7be54ccSKrishna Gudipati 
2306d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_10GBPS:
2307d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2308d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G);
2309d7be54ccSKrishna Gudipati 		break;
2310d7be54ccSKrishna Gudipati 
2311d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_8GBPS:
2312d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2313d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G);
2314d7be54ccSKrishna Gudipati 		break;
2315d7be54ccSKrishna Gudipati 
2316d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_4GBPS:
2317d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2318d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G);
2319d7be54ccSKrishna Gudipati 		break;
2320d7be54ccSKrishna Gudipati 
2321d7be54ccSKrishna Gudipati 	default:
2322d7be54ccSKrishna Gudipati 		bfa_sm_fault(port->fcs, pport_attr.speed_supported);
2323d7be54ccSKrishna Gudipati 	}
2324a36c61f9SKrishna Gudipati 
2325a36c61f9SKrishna Gudipati 	/*
2326a36c61f9SKrishna Gudipati 	 * Current Speed
2327a36c61f9SKrishna Gudipati 	 */
2328d7be54ccSKrishna Gudipati 	port_attr->curr_speed = cpu_to_be32(
2329d7be54ccSKrishna Gudipati 				bfa_fcs_fdmi_convert_speed(pport_attr.speed));
2330a36c61f9SKrishna Gudipati 
2331a36c61f9SKrishna Gudipati 	/*
2332a36c61f9SKrishna Gudipati 	 * Max PDU Size.
2333a36c61f9SKrishna Gudipati 	 */
2334ba816ea8SJing Huang 	port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ);
2335a36c61f9SKrishna Gudipati 
2336a36c61f9SKrishna Gudipati 	/*
2337a36c61f9SKrishna Gudipati 	 * OS device Name
2338a36c61f9SKrishna Gudipati 	 */
2339a36c61f9SKrishna Gudipati 	strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
2340a36c61f9SKrishna Gudipati 		sizeof(port_attr->os_device_name));
2341a36c61f9SKrishna Gudipati 
2342a36c61f9SKrishna Gudipati 	/*
2343a36c61f9SKrishna Gudipati 	 * Host name
2344a36c61f9SKrishna Gudipati 	 */
2345a36c61f9SKrishna Gudipati 	strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
2346a36c61f9SKrishna Gudipati 		sizeof(port_attr->host_name));
23477725ccfdSJing Huang 
23487725ccfdSJing Huang }
23497725ccfdSJing Huang 
2350d7be54ccSKrishna Gudipati /*
2351d7be54ccSKrishna Gudipati  * Convert BFA speed to FDMI format.
2352d7be54ccSKrishna Gudipati  */
2353d7be54ccSKrishna Gudipati u32
2354d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed)
2355d7be54ccSKrishna Gudipati {
2356d7be54ccSKrishna Gudipati 	u32	ret;
2357d7be54ccSKrishna Gudipati 
2358d7be54ccSKrishna Gudipati 	switch (pport_speed) {
2359d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_1GBPS:
2360d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_2GBPS:
2361d7be54ccSKrishna Gudipati 		ret = pport_speed;
2362d7be54ccSKrishna Gudipati 		break;
2363d7be54ccSKrishna Gudipati 
2364d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_4GBPS:
2365d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_4G;
2366d7be54ccSKrishna Gudipati 		break;
2367d7be54ccSKrishna Gudipati 
2368d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_8GBPS:
2369d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_8G;
2370d7be54ccSKrishna Gudipati 		break;
2371d7be54ccSKrishna Gudipati 
2372d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_10GBPS:
2373d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_10G;
2374d7be54ccSKrishna Gudipati 		break;
2375d7be54ccSKrishna Gudipati 
2376d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_16GBPS:
2377d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_16G;
2378d7be54ccSKrishna Gudipati 		break;
2379d7be54ccSKrishna Gudipati 
2380d7be54ccSKrishna Gudipati 	default:
2381d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_UNKNOWN;
2382d7be54ccSKrishna Gudipati 	}
2383d7be54ccSKrishna Gudipati 	return ret;
2384d7be54ccSKrishna Gudipati }
23857725ccfdSJing Huang 
2386a36c61f9SKrishna Gudipati void
2387a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms)
2388a36c61f9SKrishna Gudipati {
2389a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2390a36c61f9SKrishna Gudipati 
2391a36c61f9SKrishna Gudipati 	fdmi->ms = ms;
2392a36c61f9SKrishna Gudipati 	if (ms->port->fcs->fdmi_enabled)
2393a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
2394a36c61f9SKrishna Gudipati 	else
2395a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled);
2396a36c61f9SKrishna Gudipati }
2397a36c61f9SKrishna Gudipati 
2398a36c61f9SKrishna Gudipati void
2399a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms)
2400a36c61f9SKrishna Gudipati {
2401a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2402a36c61f9SKrishna Gudipati 
2403a36c61f9SKrishna Gudipati 	fdmi->ms = ms;
2404a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
2405a36c61f9SKrishna Gudipati }
2406a36c61f9SKrishna Gudipati 
2407a36c61f9SKrishna Gudipati void
2408a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms)
2409a36c61f9SKrishna Gudipati {
2410a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2411a36c61f9SKrishna Gudipati 
2412a36c61f9SKrishna Gudipati 	fdmi->ms = ms;
2413a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
2414a36c61f9SKrishna Gudipati }
2415a36c61f9SKrishna Gudipati 
2416a36c61f9SKrishna Gudipati #define BFA_FCS_MS_CMD_MAX_RETRIES  2
2417a36c61f9SKrishna Gudipati 
2418a36c61f9SKrishna Gudipati /*
2419a36c61f9SKrishna Gudipati  * forward declarations
2420a36c61f9SKrishna Gudipati  */
2421a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_send_plogi(void *ms_cbarg,
2422a36c61f9SKrishna Gudipati 					   struct bfa_fcxp_s *fcxp_alloced);
2423a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_timeout(void *arg);
2424a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_plogi_response(void *fcsarg,
2425a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
2426a36c61f9SKrishna Gudipati 					       void *cbarg,
2427a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
2428a36c61f9SKrishna Gudipati 					       u32 rsp_len,
2429a36c61f9SKrishna Gudipati 					       u32 resid_len,
2430a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
2431a36c61f9SKrishna Gudipati 
2432a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_ms_send_gmal(void *ms_cbarg,
2433a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
2434a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_gmal_response(void *fcsarg,
2435a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
2436a36c61f9SKrishna Gudipati 					       void *cbarg,
2437a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
2438a36c61f9SKrishna Gudipati 					       u32 rsp_len,
2439a36c61f9SKrishna Gudipati 					       u32 resid_len,
2440a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
2441a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_ms_send_gfn(void *ms_cbarg,
2442a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
2443a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_gfn_response(void *fcsarg,
2444a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
2445a36c61f9SKrishna Gudipati 					       void *cbarg,
2446a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
2447a36c61f9SKrishna Gudipati 					       u32 rsp_len,
2448a36c61f9SKrishna Gudipati 					       u32 resid_len,
2449a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
24505fbe25c7SJing Huang /*
2451a36c61f9SKrishna Gudipati  *  fcs_ms_sm FCS MS state machine
2452a36c61f9SKrishna Gudipati  */
2453a36c61f9SKrishna Gudipati 
24545fbe25c7SJing Huang /*
2455a36c61f9SKrishna Gudipati  *  MS State Machine events
2456a36c61f9SKrishna Gudipati  */
2457a36c61f9SKrishna Gudipati enum port_ms_event {
2458a36c61f9SKrishna Gudipati 	MSSM_EVENT_PORT_ONLINE = 1,
2459a36c61f9SKrishna Gudipati 	MSSM_EVENT_PORT_OFFLINE = 2,
2460a36c61f9SKrishna Gudipati 	MSSM_EVENT_RSP_OK = 3,
2461a36c61f9SKrishna Gudipati 	MSSM_EVENT_RSP_ERROR = 4,
2462a36c61f9SKrishna Gudipati 	MSSM_EVENT_TIMEOUT = 5,
2463a36c61f9SKrishna Gudipati 	MSSM_EVENT_FCXP_SENT = 6,
2464a36c61f9SKrishna Gudipati 	MSSM_EVENT_PORT_FABRIC_RSCN = 7
2465a36c61f9SKrishna Gudipati };
2466a36c61f9SKrishna Gudipati 
2467a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2468a36c61f9SKrishna Gudipati 					   enum port_ms_event event);
2469a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2470a36c61f9SKrishna Gudipati 						 enum port_ms_event event);
2471a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2472a36c61f9SKrishna Gudipati 					 enum port_ms_event event);
2473a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2474a36c61f9SKrishna Gudipati 					       enum port_ms_event event);
2475a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2476a36c61f9SKrishna Gudipati 						 enum port_ms_event event);
2477a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2478a36c61f9SKrishna Gudipati 					 enum port_ms_event event);
2479a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2480a36c61f9SKrishna Gudipati 					       enum port_ms_event event);
2481a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
2482a36c61f9SKrishna Gudipati 						 enum port_ms_event event);
2483a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2484a36c61f9SKrishna Gudipati 					 enum port_ms_event event);
2485a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2486a36c61f9SKrishna Gudipati 					       enum port_ms_event event);
2487a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2488a36c61f9SKrishna Gudipati 					  enum port_ms_event event);
24895fbe25c7SJing Huang /*
2490a36c61f9SKrishna Gudipati  *	Start in offline state - awaiting NS to send start.
2491a36c61f9SKrishna Gudipati  */
2492a36c61f9SKrishna Gudipati static void
2493a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2494a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2495a36c61f9SKrishna Gudipati {
2496a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2497a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2498a36c61f9SKrishna Gudipati 
2499a36c61f9SKrishna Gudipati 	switch (event) {
2500a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_ONLINE:
2501a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2502a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_plogi(ms, NULL);
2503a36c61f9SKrishna Gudipati 		break;
2504a36c61f9SKrishna Gudipati 
2505a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2506a36c61f9SKrishna Gudipati 		break;
2507a36c61f9SKrishna Gudipati 
2508a36c61f9SKrishna Gudipati 	default:
2509a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2510a36c61f9SKrishna Gudipati 	}
2511a36c61f9SKrishna Gudipati }
2512a36c61f9SKrishna Gudipati 
2513a36c61f9SKrishna Gudipati static void
2514a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2515a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2516a36c61f9SKrishna Gudipati {
2517a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2518a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2519a36c61f9SKrishna Gudipati 
2520a36c61f9SKrishna Gudipati 	switch (event) {
2521a36c61f9SKrishna Gudipati 	case MSSM_EVENT_FCXP_SENT:
2522a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi);
2523a36c61f9SKrishna Gudipati 		break;
2524a36c61f9SKrishna Gudipati 
2525a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2526a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2527a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2528a36c61f9SKrishna Gudipati 					   &ms->fcxp_wqe);
2529a36c61f9SKrishna Gudipati 		break;
2530a36c61f9SKrishna Gudipati 
2531a36c61f9SKrishna Gudipati 	default:
2532a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2533a36c61f9SKrishna Gudipati 	}
2534a36c61f9SKrishna Gudipati }
2535a36c61f9SKrishna Gudipati 
2536a36c61f9SKrishna Gudipati static void
2537a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2538a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2539a36c61f9SKrishna Gudipati {
2540a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2541a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2542a36c61f9SKrishna Gudipati 
2543a36c61f9SKrishna Gudipati 	switch (event) {
2544a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_ERROR:
2545a36c61f9SKrishna Gudipati 		/*
2546a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
2547a36c61f9SKrishna Gudipati 		 */
2548a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry);
2549a36c61f9SKrishna Gudipati 		ms->port->stats.ms_retries++;
2550a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2551a36c61f9SKrishna Gudipati 				    &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2552a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
2553a36c61f9SKrishna Gudipati 		break;
2554a36c61f9SKrishna Gudipati 
2555a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_OK:
2556a36c61f9SKrishna Gudipati 		/*
2557a36c61f9SKrishna Gudipati 		 * since plogi is done, now invoke MS related sub-modules
2558a36c61f9SKrishna Gudipati 		 */
2559a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_online(ms);
2560a36c61f9SKrishna Gudipati 
25615fbe25c7SJing Huang 		/*
2562a36c61f9SKrishna Gudipati 		 * if this is a Vport, go to online state.
2563a36c61f9SKrishna Gudipati 		 */
2564a36c61f9SKrishna Gudipati 		if (ms->port->vport) {
2565a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2566a36c61f9SKrishna Gudipati 			break;
2567a36c61f9SKrishna Gudipati 		}
2568a36c61f9SKrishna Gudipati 
2569a36c61f9SKrishna Gudipati 		/*
2570a36c61f9SKrishna Gudipati 		 * For a base port we need to get the
2571a36c61f9SKrishna Gudipati 		 * switch's IP address.
2572a36c61f9SKrishna Gudipati 		 */
2573a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2574a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gmal(ms, NULL);
2575a36c61f9SKrishna Gudipati 		break;
2576a36c61f9SKrishna Gudipati 
2577a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2578a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2579a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ms->fcxp);
2580a36c61f9SKrishna Gudipati 		break;
2581a36c61f9SKrishna Gudipati 
2582a36c61f9SKrishna Gudipati 	default:
2583a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2584a36c61f9SKrishna Gudipati 	}
2585a36c61f9SKrishna Gudipati }
2586a36c61f9SKrishna Gudipati 
2587a36c61f9SKrishna Gudipati static void
2588a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2589a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2590a36c61f9SKrishna Gudipati {
2591a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2592a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2593a36c61f9SKrishna Gudipati 
2594a36c61f9SKrishna Gudipati 	switch (event) {
2595a36c61f9SKrishna Gudipati 	case MSSM_EVENT_TIMEOUT:
2596a36c61f9SKrishna Gudipati 		/*
2597a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
2598a36c61f9SKrishna Gudipati 		 */
2599a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2600a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_plogi(ms, NULL);
2601a36c61f9SKrishna Gudipati 		break;
2602a36c61f9SKrishna Gudipati 
2603a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2604a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2605a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ms->timer);
2606a36c61f9SKrishna Gudipati 		break;
2607a36c61f9SKrishna Gudipati 
2608a36c61f9SKrishna Gudipati 	default:
2609a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2610a36c61f9SKrishna Gudipati 	}
2611a36c61f9SKrishna Gudipati }
2612a36c61f9SKrishna Gudipati 
2613a36c61f9SKrishna Gudipati static void
2614a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2615a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2616a36c61f9SKrishna Gudipati {
2617a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2618a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2619a36c61f9SKrishna Gudipati 
2620a36c61f9SKrishna Gudipati 	switch (event) {
2621a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2622a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2623a36c61f9SKrishna Gudipati 		break;
2624a36c61f9SKrishna Gudipati 
2625a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_FABRIC_RSCN:
2626a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2627a36c61f9SKrishna Gudipati 		ms->retry_cnt = 0;
2628a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gfn(ms, NULL);
2629a36c61f9SKrishna Gudipati 		break;
2630a36c61f9SKrishna Gudipati 
2631a36c61f9SKrishna Gudipati 	default:
2632a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2633a36c61f9SKrishna Gudipati 	}
2634a36c61f9SKrishna Gudipati }
2635a36c61f9SKrishna Gudipati 
2636a36c61f9SKrishna Gudipati static void
2637a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2638a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2639a36c61f9SKrishna Gudipati {
2640a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2641a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2642a36c61f9SKrishna Gudipati 
2643a36c61f9SKrishna Gudipati 	switch (event) {
2644a36c61f9SKrishna Gudipati 	case MSSM_EVENT_FCXP_SENT:
2645a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal);
2646a36c61f9SKrishna Gudipati 		break;
2647a36c61f9SKrishna Gudipati 
2648a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2649a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2650a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2651a36c61f9SKrishna Gudipati 					   &ms->fcxp_wqe);
2652a36c61f9SKrishna Gudipati 		break;
2653a36c61f9SKrishna Gudipati 
2654a36c61f9SKrishna Gudipati 	default:
2655a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2656a36c61f9SKrishna Gudipati 	}
2657a36c61f9SKrishna Gudipati }
2658a36c61f9SKrishna Gudipati 
2659a36c61f9SKrishna Gudipati static void
2660a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2661a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2662a36c61f9SKrishna Gudipati {
2663a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2664a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2665a36c61f9SKrishna Gudipati 
2666a36c61f9SKrishna Gudipati 	switch (event) {
2667a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_ERROR:
2668a36c61f9SKrishna Gudipati 		/*
2669a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
2670a36c61f9SKrishna Gudipati 		 */
2671a36c61f9SKrishna Gudipati 		if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
2672a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry);
2673a36c61f9SKrishna Gudipati 			ms->port->stats.ms_retries++;
2674a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2675a36c61f9SKrishna Gudipati 				&ms->timer, bfa_fcs_lport_ms_timeout, ms,
2676a36c61f9SKrishna Gudipati 				BFA_FCS_RETRY_TIMEOUT);
2677a36c61f9SKrishna Gudipati 		} else {
2678a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2679a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ms_send_gfn(ms, NULL);
2680a36c61f9SKrishna Gudipati 			ms->retry_cnt = 0;
2681a36c61f9SKrishna Gudipati 		}
2682a36c61f9SKrishna Gudipati 		break;
2683a36c61f9SKrishna Gudipati 
2684a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_OK:
2685a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2686a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gfn(ms, NULL);
2687a36c61f9SKrishna Gudipati 		break;
2688a36c61f9SKrishna Gudipati 
2689a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2690a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2691a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ms->fcxp);
2692a36c61f9SKrishna Gudipati 		break;
2693a36c61f9SKrishna Gudipati 
2694a36c61f9SKrishna Gudipati 	default:
2695a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2696a36c61f9SKrishna Gudipati 	}
2697a36c61f9SKrishna Gudipati }
2698a36c61f9SKrishna Gudipati 
2699a36c61f9SKrishna Gudipati static void
2700a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2701a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2702a36c61f9SKrishna Gudipati {
2703a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2704a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2705a36c61f9SKrishna Gudipati 
2706a36c61f9SKrishna Gudipati 	switch (event) {
2707a36c61f9SKrishna Gudipati 	case MSSM_EVENT_TIMEOUT:
2708a36c61f9SKrishna Gudipati 		/*
2709a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
2710a36c61f9SKrishna Gudipati 		 */
2711a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2712a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gmal(ms, NULL);
2713a36c61f9SKrishna Gudipati 		break;
2714a36c61f9SKrishna Gudipati 
2715a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2716a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2717a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ms->timer);
2718a36c61f9SKrishna Gudipati 		break;
2719a36c61f9SKrishna Gudipati 
2720a36c61f9SKrishna Gudipati 	default:
2721a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2722a36c61f9SKrishna Gudipati 	}
2723a36c61f9SKrishna Gudipati }
27245fbe25c7SJing Huang /*
2725a36c61f9SKrishna Gudipati  *  ms_pvt MS local functions
2726a36c61f9SKrishna Gudipati  */
2727a36c61f9SKrishna Gudipati 
2728a36c61f9SKrishna Gudipati static void
2729a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2730a36c61f9SKrishna Gudipati {
2731a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2732a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
2733a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2734a36c61f9SKrishna Gudipati 	int		len;
2735a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2736a36c61f9SKrishna Gudipati 
2737a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
2738a36c61f9SKrishna Gudipati 
2739a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2740a36c61f9SKrishna Gudipati 	if (!fcxp) {
2741a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2742a36c61f9SKrishna Gudipati 					bfa_fcs_lport_ms_send_gmal, ms);
2743a36c61f9SKrishna Gudipati 		return;
2744a36c61f9SKrishna Gudipati 	}
2745a36c61f9SKrishna Gudipati 	ms->fcxp = fcxp;
2746a36c61f9SKrishna Gudipati 
2747a36c61f9SKrishna Gudipati 	len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2748a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port),
2749f7f73812SMaggie Zhang 				 port->fabric->lps->pr_nwwn);
2750a36c61f9SKrishna Gudipati 
2751a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2752a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
2753a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ms_gmal_response, (void *)ms,
2754a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
2755a36c61f9SKrishna Gudipati 
2756a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
2757a36c61f9SKrishna Gudipati }
2758a36c61f9SKrishna Gudipati 
2759a36c61f9SKrishna Gudipati static void
2760a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2761a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
2762a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
2763a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
2764a36c61f9SKrishna Gudipati {
2765a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
2766a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
2767a36c61f9SKrishna Gudipati 	struct ct_hdr_s		*cthdr = NULL;
2768a36c61f9SKrishna Gudipati 	struct fcgs_gmal_resp_s *gmal_resp;
2769a36c61f9SKrishna Gudipati 	struct fcgs_gmal_entry_s *gmal_entry;
2770a36c61f9SKrishna Gudipati 	u32		num_entries;
2771a36c61f9SKrishna Gudipati 	u8			*rsp_str;
2772a36c61f9SKrishna Gudipati 
2773a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
2774a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2775a36c61f9SKrishna Gudipati 
2776a36c61f9SKrishna Gudipati 	/*
2777a36c61f9SKrishna Gudipati 	 * Sanity Checks
2778a36c61f9SKrishna Gudipati 	 */
2779a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2780a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
2781a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2782a36c61f9SKrishna Gudipati 		return;
2783a36c61f9SKrishna Gudipati 	}
2784a36c61f9SKrishna Gudipati 
2785a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2786ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2787a36c61f9SKrishna Gudipati 
2788a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2789a36c61f9SKrishna Gudipati 		gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
2790a36c61f9SKrishna Gudipati 
2791ba816ea8SJing Huang 		num_entries = be32_to_cpu(gmal_resp->ms_len);
2792a36c61f9SKrishna Gudipati 		if (num_entries == 0) {
2793a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2794a36c61f9SKrishna Gudipati 			return;
2795a36c61f9SKrishna Gudipati 		}
2796a36c61f9SKrishna Gudipati 		/*
2797a36c61f9SKrishna Gudipati 		* The response could contain multiple Entries.
2798a36c61f9SKrishna Gudipati 		* Entries for SNMP interface, etc.
2799a36c61f9SKrishna Gudipati 		* We look for the entry with a telnet prefix.
2800a36c61f9SKrishna Gudipati 		* First "http://" entry refers to IP addr
2801a36c61f9SKrishna Gudipati 		*/
2802a36c61f9SKrishna Gudipati 
2803a36c61f9SKrishna Gudipati 		gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma;
2804a36c61f9SKrishna Gudipati 		while (num_entries > 0) {
2805a36c61f9SKrishna Gudipati 			if (strncmp(gmal_entry->prefix,
2806a36c61f9SKrishna Gudipati 				CT_GMAL_RESP_PREFIX_HTTP,
2807a36c61f9SKrishna Gudipati 				sizeof(gmal_entry->prefix)) == 0) {
2808a36c61f9SKrishna Gudipati 
2809a36c61f9SKrishna Gudipati 				/*
2810a36c61f9SKrishna Gudipati 				* if the IP address is terminating with a '/',
2811a36c61f9SKrishna Gudipati 				* remove it.
2812a36c61f9SKrishna Gudipati 				* Byte 0 consists of the length of the string.
2813a36c61f9SKrishna Gudipati 				*/
2814a36c61f9SKrishna Gudipati 				rsp_str = &(gmal_entry->prefix[0]);
2815a36c61f9SKrishna Gudipati 				if (rsp_str[gmal_entry->len-1] == '/')
2816a36c61f9SKrishna Gudipati 					rsp_str[gmal_entry->len-1] = 0;
2817a36c61f9SKrishna Gudipati 
2818a36c61f9SKrishna Gudipati 				/* copy IP Address to fabric */
2819a36c61f9SKrishna Gudipati 				strncpy(bfa_fcs_lport_get_fabric_ipaddr(port),
2820a36c61f9SKrishna Gudipati 					gmal_entry->ip_addr,
2821a36c61f9SKrishna Gudipati 					BFA_FCS_FABRIC_IPADDR_SZ);
2822a36c61f9SKrishna Gudipati 				break;
2823a36c61f9SKrishna Gudipati 			} else {
2824a36c61f9SKrishna Gudipati 				--num_entries;
2825a36c61f9SKrishna Gudipati 				++gmal_entry;
2826a36c61f9SKrishna Gudipati 			}
2827a36c61f9SKrishna Gudipati 		}
2828a36c61f9SKrishna Gudipati 
2829a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
2830a36c61f9SKrishna Gudipati 		return;
2831a36c61f9SKrishna Gudipati 	}
2832a36c61f9SKrishna Gudipati 
2833a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
2834a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
2835a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2836a36c61f9SKrishna Gudipati }
2837a36c61f9SKrishna Gudipati 
2838a36c61f9SKrishna Gudipati static void
2839a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
2840a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2841a36c61f9SKrishna Gudipati {
2842a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2843a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2844a36c61f9SKrishna Gudipati 
2845a36c61f9SKrishna Gudipati 	switch (event) {
2846a36c61f9SKrishna Gudipati 	case MSSM_EVENT_FCXP_SENT:
2847a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn);
2848a36c61f9SKrishna Gudipati 		break;
2849a36c61f9SKrishna Gudipati 
2850a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2851a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2852a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2853a36c61f9SKrishna Gudipati 					   &ms->fcxp_wqe);
2854a36c61f9SKrishna Gudipati 		break;
2855a36c61f9SKrishna Gudipati 
2856a36c61f9SKrishna Gudipati 	default:
2857a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2858a36c61f9SKrishna Gudipati 	}
2859a36c61f9SKrishna Gudipati }
2860a36c61f9SKrishna Gudipati 
2861a36c61f9SKrishna Gudipati static void
2862a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2863a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2864a36c61f9SKrishna Gudipati {
2865a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2866a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2867a36c61f9SKrishna Gudipati 
2868a36c61f9SKrishna Gudipati 	switch (event) {
2869a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_ERROR:
2870a36c61f9SKrishna Gudipati 		/*
2871a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
2872a36c61f9SKrishna Gudipati 		 */
2873a36c61f9SKrishna Gudipati 		if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
2874a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry);
2875a36c61f9SKrishna Gudipati 			ms->port->stats.ms_retries++;
2876a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2877a36c61f9SKrishna Gudipati 				&ms->timer, bfa_fcs_lport_ms_timeout, ms,
2878a36c61f9SKrishna Gudipati 				BFA_FCS_RETRY_TIMEOUT);
2879a36c61f9SKrishna Gudipati 		} else {
2880a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2881a36c61f9SKrishna Gudipati 			ms->retry_cnt = 0;
2882a36c61f9SKrishna Gudipati 		}
2883a36c61f9SKrishna Gudipati 		break;
2884a36c61f9SKrishna Gudipati 
2885a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_OK:
2886a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2887a36c61f9SKrishna Gudipati 		break;
2888a36c61f9SKrishna Gudipati 
2889a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2890a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2891a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ms->fcxp);
2892a36c61f9SKrishna Gudipati 		break;
2893a36c61f9SKrishna Gudipati 
2894a36c61f9SKrishna Gudipati 	default:
2895a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2896a36c61f9SKrishna Gudipati 	}
2897a36c61f9SKrishna Gudipati }
2898a36c61f9SKrishna Gudipati 
2899a36c61f9SKrishna Gudipati static void
2900a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2901a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2902a36c61f9SKrishna Gudipati {
2903a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2904a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2905a36c61f9SKrishna Gudipati 
2906a36c61f9SKrishna Gudipati 	switch (event) {
2907a36c61f9SKrishna Gudipati 	case MSSM_EVENT_TIMEOUT:
2908a36c61f9SKrishna Gudipati 		/*
2909a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
2910a36c61f9SKrishna Gudipati 		 */
2911a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2912a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gfn(ms, NULL);
2913a36c61f9SKrishna Gudipati 		break;
2914a36c61f9SKrishna Gudipati 
2915a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2916a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2917a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ms->timer);
2918a36c61f9SKrishna Gudipati 		break;
2919a36c61f9SKrishna Gudipati 
2920a36c61f9SKrishna Gudipati 	default:
2921a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2922a36c61f9SKrishna Gudipati 	}
2923a36c61f9SKrishna Gudipati }
29245fbe25c7SJing Huang /*
2925a36c61f9SKrishna Gudipati  *  ms_pvt MS local functions
2926a36c61f9SKrishna Gudipati  */
2927a36c61f9SKrishna Gudipati 
2928a36c61f9SKrishna Gudipati static void
2929a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2930a36c61f9SKrishna Gudipati {
2931a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2932a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
2933a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
2934a36c61f9SKrishna Gudipati 	int			len;
2935a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2936a36c61f9SKrishna Gudipati 
2937a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
2938a36c61f9SKrishna Gudipati 
2939a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2940a36c61f9SKrishna Gudipati 	if (!fcxp) {
2941a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2942a36c61f9SKrishna Gudipati 					bfa_fcs_lport_ms_send_gfn, ms);
2943a36c61f9SKrishna Gudipati 		return;
2944a36c61f9SKrishna Gudipati 	}
2945a36c61f9SKrishna Gudipati 	ms->fcxp = fcxp;
2946a36c61f9SKrishna Gudipati 
2947a36c61f9SKrishna Gudipati 	len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2948a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port),
2949f7f73812SMaggie Zhang 				 port->fabric->lps->pr_nwwn);
2950a36c61f9SKrishna Gudipati 
2951a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2952a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
2953a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ms_gfn_response, (void *)ms,
2954a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
2955a36c61f9SKrishna Gudipati 
2956a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
2957a36c61f9SKrishna Gudipati }
2958a36c61f9SKrishna Gudipati 
2959a36c61f9SKrishna Gudipati static void
2960a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2961a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
2962a36c61f9SKrishna Gudipati 			u32 resid_len, struct fchs_s *rsp_fchs)
2963a36c61f9SKrishna Gudipati {
2964a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
2965a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
2966a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr = NULL;
2967a36c61f9SKrishna Gudipati 	wwn_t	       *gfn_resp;
2968a36c61f9SKrishna Gudipati 
2969a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
2970a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2971a36c61f9SKrishna Gudipati 
2972a36c61f9SKrishna Gudipati 	/*
2973a36c61f9SKrishna Gudipati 	 * Sanity Checks
2974a36c61f9SKrishna Gudipati 	 */
2975a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2976a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
2977a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2978a36c61f9SKrishna Gudipati 		return;
2979a36c61f9SKrishna Gudipati 	}
2980a36c61f9SKrishna Gudipati 
2981a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2982ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2983a36c61f9SKrishna Gudipati 
2984a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2985a36c61f9SKrishna Gudipati 		gfn_resp = (wwn_t *)(cthdr + 1);
2986a36c61f9SKrishna Gudipati 		/* check if it has actually changed */
2987a36c61f9SKrishna Gudipati 		if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port),
2988a36c61f9SKrishna Gudipati 				gfn_resp, sizeof(wwn_t)) != 0)) {
2989a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
2990a36c61f9SKrishna Gudipati 		}
2991a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
2992a36c61f9SKrishna Gudipati 		return;
2993a36c61f9SKrishna Gudipati 	}
2994a36c61f9SKrishna Gudipati 
2995a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
2996a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
2997a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2998a36c61f9SKrishna Gudipati }
2999a36c61f9SKrishna Gudipati 
30005fbe25c7SJing Huang /*
3001a36c61f9SKrishna Gudipati  *  ms_pvt MS local functions
3002a36c61f9SKrishna Gudipati  */
3003a36c61f9SKrishna Gudipati 
3004a36c61f9SKrishna Gudipati static void
3005a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3006a36c61f9SKrishna Gudipati {
3007a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
3008a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ms->port;
3009a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
3010a36c61f9SKrishna Gudipati 	int	len;
3011a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3012a36c61f9SKrishna Gudipati 
3013a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
3014a36c61f9SKrishna Gudipati 
3015a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3016a36c61f9SKrishna Gudipati 	if (!fcxp) {
3017a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_alloc_wait++;
3018a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3019a36c61f9SKrishna Gudipati 					bfa_fcs_lport_ms_send_plogi, ms);
3020a36c61f9SKrishna Gudipati 		return;
3021a36c61f9SKrishna Gudipati 	}
3022a36c61f9SKrishna Gudipati 	ms->fcxp = fcxp;
3023a36c61f9SKrishna Gudipati 
3024a36c61f9SKrishna Gudipati 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3025f16a1750SMaggie Zhang 			     bfa_hton3b(FC_MGMT_SERVER),
3026a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port), 0,
3027a36c61f9SKrishna Gudipati 			     port->port_cfg.pwwn, port->port_cfg.nwwn,
3028be540a99SKrishna Gudipati 			     bfa_fcport_get_maxfrsize(port->fcs->bfa),
3029be540a99SKrishna Gudipati 			     bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
3030a36c61f9SKrishna Gudipati 
3031a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3032a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3033a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ms_plogi_response, (void *)ms,
3034a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_ELS_TOV);
3035a36c61f9SKrishna Gudipati 
3036a36c61f9SKrishna Gudipati 	port->stats.ms_plogi_sent++;
3037a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
3038a36c61f9SKrishna Gudipati }
3039a36c61f9SKrishna Gudipati 
3040a36c61f9SKrishna Gudipati static void
3041a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3042a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status,
3043a36c61f9SKrishna Gudipati 			u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs)
3044a36c61f9SKrishna Gudipati {
3045a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3046a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ms->port;
3047a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd;
3048a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
3049a36c61f9SKrishna Gudipati 
3050a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
3051a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3052a36c61f9SKrishna Gudipati 
3053a36c61f9SKrishna Gudipati 	/*
3054a36c61f9SKrishna Gudipati 	 * Sanity Checks
3055a36c61f9SKrishna Gudipati 	 */
3056a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3057a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_rsp_err++;
3058a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
3059a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3060a36c61f9SKrishna Gudipati 		return;
3061a36c61f9SKrishna Gudipati 	}
3062a36c61f9SKrishna Gudipati 
3063a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
3064a36c61f9SKrishna Gudipati 
3065a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
3066a36c61f9SKrishna Gudipati 
3067a36c61f9SKrishna Gudipati 	case FC_ELS_ACC:
3068a36c61f9SKrishna Gudipati 		if (rsp_len < sizeof(struct fc_logi_s)) {
3069a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rsp_len);
3070a36c61f9SKrishna Gudipati 			port->stats.ms_plogi_acc_err++;
3071a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3072a36c61f9SKrishna Gudipati 			break;
3073a36c61f9SKrishna Gudipati 		}
3074a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_accepts++;
3075a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
3076a36c61f9SKrishna Gudipati 		break;
3077a36c61f9SKrishna Gudipati 
3078a36c61f9SKrishna Gudipati 	case FC_ELS_LS_RJT:
3079a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3080a36c61f9SKrishna Gudipati 
3081a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code);
3082a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code_expl);
3083a36c61f9SKrishna Gudipati 
3084a36c61f9SKrishna Gudipati 		port->stats.ms_rejects++;
3085a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3086a36c61f9SKrishna Gudipati 		break;
3087a36c61f9SKrishna Gudipati 
3088a36c61f9SKrishna Gudipati 	default:
3089a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_unknown_rsp++;
3090a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, els_cmd->els_code);
3091a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3092a36c61f9SKrishna Gudipati 	}
3093a36c61f9SKrishna Gudipati }
3094a36c61f9SKrishna Gudipati 
3095a36c61f9SKrishna Gudipati static void
3096a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_timeout(void *arg)
3097a36c61f9SKrishna Gudipati {
3098a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg;
3099a36c61f9SKrishna Gudipati 
3100a36c61f9SKrishna Gudipati 	ms->port->stats.ms_timeouts++;
3101a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
3102a36c61f9SKrishna Gudipati }
3103a36c61f9SKrishna Gudipati 
3104a36c61f9SKrishna Gudipati 
3105a36c61f9SKrishna Gudipati void
3106a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port)
3107a36c61f9SKrishna Gudipati {
3108a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3109a36c61f9SKrishna Gudipati 
3110a36c61f9SKrishna Gudipati 	ms->port = port;
3111a36c61f9SKrishna Gudipati 	bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3112a36c61f9SKrishna Gudipati 
3113a36c61f9SKrishna Gudipati 	/*
3114a36c61f9SKrishna Gudipati 	 * Invoke init routines of sub modules.
3115a36c61f9SKrishna Gudipati 	 */
3116a36c61f9SKrishna Gudipati 	bfa_fcs_lport_fdmi_init(ms);
3117a36c61f9SKrishna Gudipati }
3118a36c61f9SKrishna Gudipati 
3119a36c61f9SKrishna Gudipati void
3120a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port)
3121a36c61f9SKrishna Gudipati {
3122a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3123a36c61f9SKrishna Gudipati 
3124a36c61f9SKrishna Gudipati 	ms->port = port;
3125a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
3126a36c61f9SKrishna Gudipati 	bfa_fcs_lport_fdmi_offline(ms);
3127a36c61f9SKrishna Gudipati }
3128a36c61f9SKrishna Gudipati 
3129a36c61f9SKrishna Gudipati void
3130a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port)
3131a36c61f9SKrishna Gudipati {
3132a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3133a36c61f9SKrishna Gudipati 
3134a36c61f9SKrishna Gudipati 	ms->port = port;
3135a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
3136a36c61f9SKrishna Gudipati }
3137a36c61f9SKrishna Gudipati void
3138a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port)
3139a36c61f9SKrishna Gudipati {
3140a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3141a36c61f9SKrishna Gudipati 
3142a36c61f9SKrishna Gudipati 	/* todo.  Handle this only  when in Online state */
3143a36c61f9SKrishna Gudipati 	if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online))
3144a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
3145a36c61f9SKrishna Gudipati }
3146a36c61f9SKrishna Gudipati 
31475fbe25c7SJing Huang /*
3148a36c61f9SKrishna Gudipati  * @page ns_sm_info VPORT NS State Machine
3149a36c61f9SKrishna Gudipati  *
3150a36c61f9SKrishna Gudipati  * @section ns_sm_interactions VPORT NS State Machine Interactions
3151a36c61f9SKrishna Gudipati  *
3152a36c61f9SKrishna Gudipati  * @section ns_sm VPORT NS State Machine
3153a36c61f9SKrishna Gudipati  * img ns_sm.jpg
3154a36c61f9SKrishna Gudipati  */
3155a36c61f9SKrishna Gudipati 
3156a36c61f9SKrishna Gudipati /*
3157a36c61f9SKrishna Gudipati  * forward declarations
3158a36c61f9SKrishna Gudipati  */
3159a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_plogi(void *ns_cbarg,
3160a36c61f9SKrishna Gudipati 					   struct bfa_fcxp_s *fcxp_alloced);
3161a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg,
3162a36c61f9SKrishna Gudipati 					     struct bfa_fcxp_s *fcxp_alloced);
3163a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg,
3164a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
3165a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg,
3166a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
3167a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg,
3168a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
3169a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_timeout(void *arg);
3170a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_plogi_response(void *fcsarg,
3171a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
3172a36c61f9SKrishna Gudipati 					       void *cbarg,
3173a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
3174a36c61f9SKrishna Gudipati 					       u32 rsp_len,
3175a36c61f9SKrishna Gudipati 					       u32 resid_len,
3176a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
3177a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_rspn_id_response(void *fcsarg,
3178a36c61f9SKrishna Gudipati 						 struct bfa_fcxp_s *fcxp,
3179a36c61f9SKrishna Gudipati 						 void *cbarg,
3180a36c61f9SKrishna Gudipati 						 bfa_status_t req_status,
3181a36c61f9SKrishna Gudipati 						 u32 rsp_len,
3182a36c61f9SKrishna Gudipati 						 u32 resid_len,
3183a36c61f9SKrishna Gudipati 						 struct fchs_s *rsp_fchs);
3184a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_rft_id_response(void *fcsarg,
3185a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3186a36c61f9SKrishna Gudipati 						void *cbarg,
3187a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
3188a36c61f9SKrishna Gudipati 						u32 rsp_len,
3189a36c61f9SKrishna Gudipati 						u32 resid_len,
3190a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3191a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_rff_id_response(void *fcsarg,
3192a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3193a36c61f9SKrishna Gudipati 						void *cbarg,
3194a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
3195a36c61f9SKrishna Gudipati 						u32 rsp_len,
3196a36c61f9SKrishna Gudipati 						u32 resid_len,
3197a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3198a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_gid_ft_response(void *fcsarg,
3199a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3200a36c61f9SKrishna Gudipati 						void *cbarg,
3201a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
3202a36c61f9SKrishna Gudipati 						u32 rsp_len,
3203a36c61f9SKrishna Gudipati 						u32 resid_len,
3204a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3205a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_process_gidft_pids(
3206a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_s *port,
3207a36c61f9SKrishna Gudipati 				u32 *pid_buf, u32 n_pids);
3208a36c61f9SKrishna Gudipati 
3209a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port);
32105fbe25c7SJing Huang /*
3211a36c61f9SKrishna Gudipati  *  fcs_ns_sm FCS nameserver interface state machine
3212a36c61f9SKrishna Gudipati  */
3213a36c61f9SKrishna Gudipati 
32145fbe25c7SJing Huang /*
3215a36c61f9SKrishna Gudipati  * VPort NS State Machine events
3216a36c61f9SKrishna Gudipati  */
3217a36c61f9SKrishna Gudipati enum vport_ns_event {
3218a36c61f9SKrishna Gudipati 	NSSM_EVENT_PORT_ONLINE = 1,
3219a36c61f9SKrishna Gudipati 	NSSM_EVENT_PORT_OFFLINE = 2,
3220a36c61f9SKrishna Gudipati 	NSSM_EVENT_PLOGI_SENT = 3,
3221a36c61f9SKrishna Gudipati 	NSSM_EVENT_RSP_OK = 4,
3222a36c61f9SKrishna Gudipati 	NSSM_EVENT_RSP_ERROR = 5,
3223a36c61f9SKrishna Gudipati 	NSSM_EVENT_TIMEOUT = 6,
3224a36c61f9SKrishna Gudipati 	NSSM_EVENT_NS_QUERY = 7,
3225a36c61f9SKrishna Gudipati 	NSSM_EVENT_RSPNID_SENT = 8,
3226a36c61f9SKrishna Gudipati 	NSSM_EVENT_RFTID_SENT = 9,
3227a36c61f9SKrishna Gudipati 	NSSM_EVENT_RFFID_SENT = 10,
3228a36c61f9SKrishna Gudipati 	NSSM_EVENT_GIDFT_SENT = 11,
3229a36c61f9SKrishna Gudipati };
3230a36c61f9SKrishna Gudipati 
3231a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3232a36c61f9SKrishna Gudipati 					   enum vport_ns_event event);
3233a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3234a36c61f9SKrishna Gudipati 						 enum vport_ns_event event);
3235a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3236a36c61f9SKrishna Gudipati 					 enum vport_ns_event event);
3237a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3238a36c61f9SKrishna Gudipati 					       enum vport_ns_event event);
3239a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rspn_id(
3240a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3241a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3242a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3243a36c61f9SKrishna Gudipati 					   enum vport_ns_event event);
3244a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3245a36c61f9SKrishna Gudipati 						 enum vport_ns_event event);
3246a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rft_id(
3247a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3248a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3249a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3250a36c61f9SKrishna Gudipati 						enum vport_ns_event event);
3251a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3252a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
3253a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rff_id(
3254a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3255a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3256a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3257a36c61f9SKrishna Gudipati 						enum vport_ns_event event);
3258a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3259a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
3260a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_gid_ft(
3261a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3262a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3263a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3264a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
3265a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3266a36c61f9SKrishna Gudipati 						enum vport_ns_event event);
3267a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3268a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
32695fbe25c7SJing Huang /*
3270a36c61f9SKrishna Gudipati  *	Start in offline state - awaiting linkup
3271a36c61f9SKrishna Gudipati  */
3272a36c61f9SKrishna Gudipati static void
3273a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3274a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3275a36c61f9SKrishna Gudipati {
3276a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3277a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3278a36c61f9SKrishna Gudipati 
3279a36c61f9SKrishna Gudipati 	switch (event) {
3280a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_ONLINE:
3281a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3282a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_plogi(ns, NULL);
3283a36c61f9SKrishna Gudipati 		break;
3284a36c61f9SKrishna Gudipati 
3285a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3286a36c61f9SKrishna Gudipati 		break;
3287a36c61f9SKrishna Gudipati 
3288a36c61f9SKrishna Gudipati 	default:
3289a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3290a36c61f9SKrishna Gudipati 	}
3291a36c61f9SKrishna Gudipati }
3292a36c61f9SKrishna Gudipati 
3293a36c61f9SKrishna Gudipati static void
3294a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3295a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3296a36c61f9SKrishna Gudipati {
3297a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3298a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3299a36c61f9SKrishna Gudipati 
3300a36c61f9SKrishna Gudipati 	switch (event) {
3301a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PLOGI_SENT:
3302a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi);
3303a36c61f9SKrishna Gudipati 		break;
3304a36c61f9SKrishna Gudipati 
3305a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3306a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3307a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3308a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3309a36c61f9SKrishna Gudipati 		break;
3310a36c61f9SKrishna Gudipati 
3311a36c61f9SKrishna Gudipati 	default:
3312a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3313a36c61f9SKrishna Gudipati 	}
3314a36c61f9SKrishna Gudipati }
3315a36c61f9SKrishna Gudipati 
3316a36c61f9SKrishna Gudipati static void
3317a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3318a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3319a36c61f9SKrishna Gudipati {
3320a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3321a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3322a36c61f9SKrishna Gudipati 
3323a36c61f9SKrishna Gudipati 	switch (event) {
3324a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3325a36c61f9SKrishna Gudipati 		/*
3326a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3327a36c61f9SKrishna Gudipati 		 */
3328a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry);
3329a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3330a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3331a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3332a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3333a36c61f9SKrishna Gudipati 		break;
3334a36c61f9SKrishna Gudipati 
3335a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3336a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3337a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3338a36c61f9SKrishna Gudipati 		break;
3339a36c61f9SKrishna Gudipati 
3340a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3341a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3342a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3343a36c61f9SKrishna Gudipati 		break;
3344a36c61f9SKrishna Gudipati 
3345a36c61f9SKrishna Gudipati 	default:
3346a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3347a36c61f9SKrishna Gudipati 	}
3348a36c61f9SKrishna Gudipati }
3349a36c61f9SKrishna Gudipati 
3350a36c61f9SKrishna Gudipati static void
3351a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3352a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3353a36c61f9SKrishna Gudipati {
3354a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3355a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3356a36c61f9SKrishna Gudipati 
3357a36c61f9SKrishna Gudipati 	switch (event) {
3358a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3359a36c61f9SKrishna Gudipati 		/*
3360a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
3361a36c61f9SKrishna Gudipati 		 */
3362a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3363a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_plogi(ns, NULL);
3364a36c61f9SKrishna Gudipati 		break;
3365a36c61f9SKrishna Gudipati 
3366a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3367a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3368a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3369a36c61f9SKrishna Gudipati 		break;
3370a36c61f9SKrishna Gudipati 
3371a36c61f9SKrishna Gudipati 	default:
3372a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3373a36c61f9SKrishna Gudipati 	}
3374a36c61f9SKrishna Gudipati }
3375a36c61f9SKrishna Gudipati 
3376a36c61f9SKrishna Gudipati static void
3377a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3378a36c61f9SKrishna Gudipati 				   enum vport_ns_event event)
3379a36c61f9SKrishna Gudipati {
3380a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3381a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3382a36c61f9SKrishna Gudipati 
3383a36c61f9SKrishna Gudipati 	switch (event) {
3384a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSPNID_SENT:
3385a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id);
3386a36c61f9SKrishna Gudipati 		break;
3387a36c61f9SKrishna Gudipati 
3388a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3389a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3390a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3391a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3392a36c61f9SKrishna Gudipati 		break;
3393a36c61f9SKrishna Gudipati 
3394a36c61f9SKrishna Gudipati 	default:
3395a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3396a36c61f9SKrishna Gudipati 	}
3397a36c61f9SKrishna Gudipati }
3398a36c61f9SKrishna Gudipati 
3399a36c61f9SKrishna Gudipati static void
3400a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3401a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3402a36c61f9SKrishna Gudipati {
3403a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3404a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3405a36c61f9SKrishna Gudipati 
3406a36c61f9SKrishna Gudipati 	switch (event) {
3407a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3408a36c61f9SKrishna Gudipati 		/*
3409a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3410a36c61f9SKrishna Gudipati 		 */
3411a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry);
3412a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3413a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3414a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3415a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3416a36c61f9SKrishna Gudipati 		break;
3417a36c61f9SKrishna Gudipati 
3418a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3419a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
3420a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rft_id(ns, NULL);
3421a36c61f9SKrishna Gudipati 		break;
3422a36c61f9SKrishna Gudipati 
3423a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3424a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3425a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3426a36c61f9SKrishna Gudipati 		break;
3427a36c61f9SKrishna Gudipati 
3428a36c61f9SKrishna Gudipati 	default:
3429a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3430a36c61f9SKrishna Gudipati 	}
3431a36c61f9SKrishna Gudipati }
3432a36c61f9SKrishna Gudipati 
3433a36c61f9SKrishna Gudipati static void
3434a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3435a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3436a36c61f9SKrishna Gudipati {
3437a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3438a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3439a36c61f9SKrishna Gudipati 
3440a36c61f9SKrishna Gudipati 	switch (event) {
3441a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3442a36c61f9SKrishna Gudipati 		/*
3443a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
3444a36c61f9SKrishna Gudipati 		 */
3445a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3446a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3447a36c61f9SKrishna Gudipati 		break;
3448a36c61f9SKrishna Gudipati 
3449a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3450a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3451a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3452a36c61f9SKrishna Gudipati 		break;
3453a36c61f9SKrishna Gudipati 
3454a36c61f9SKrishna Gudipati 	default:
3455a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3456a36c61f9SKrishna Gudipati 	}
3457a36c61f9SKrishna Gudipati }
3458a36c61f9SKrishna Gudipati 
3459a36c61f9SKrishna Gudipati static void
3460a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns,
3461a36c61f9SKrishna Gudipati 				  enum vport_ns_event event)
3462a36c61f9SKrishna Gudipati {
3463a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3464a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3465a36c61f9SKrishna Gudipati 
3466a36c61f9SKrishna Gudipati 	switch (event) {
3467a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RFTID_SENT:
3468a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id);
3469a36c61f9SKrishna Gudipati 		break;
3470a36c61f9SKrishna Gudipati 
3471a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3472a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3473a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3474a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3475a36c61f9SKrishna Gudipati 		break;
3476a36c61f9SKrishna Gudipati 
3477a36c61f9SKrishna Gudipati 	default:
3478a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3479a36c61f9SKrishna Gudipati 	}
3480a36c61f9SKrishna Gudipati }
3481a36c61f9SKrishna Gudipati 
3482a36c61f9SKrishna Gudipati static void
3483a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3484a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3485a36c61f9SKrishna Gudipati {
3486a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3487a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3488a36c61f9SKrishna Gudipati 
3489a36c61f9SKrishna Gudipati 	switch (event) {
3490a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3491a36c61f9SKrishna Gudipati 		/* Now move to register FC4 Features */
3492a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
3493a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rff_id(ns, NULL);
3494a36c61f9SKrishna Gudipati 		break;
3495a36c61f9SKrishna Gudipati 
3496a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3497a36c61f9SKrishna Gudipati 		/*
3498a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3499a36c61f9SKrishna Gudipati 		 */
3500a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry);
3501a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3502a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3503a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3504a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3505a36c61f9SKrishna Gudipati 		break;
3506a36c61f9SKrishna Gudipati 
3507a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3508a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3509a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3510a36c61f9SKrishna Gudipati 		break;
3511a36c61f9SKrishna Gudipati 
3512a36c61f9SKrishna Gudipati 	default:
3513a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3514a36c61f9SKrishna Gudipati 	}
3515a36c61f9SKrishna Gudipati }
3516a36c61f9SKrishna Gudipati 
3517a36c61f9SKrishna Gudipati static void
3518a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3519a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3520a36c61f9SKrishna Gudipati {
3521a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3522a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3523a36c61f9SKrishna Gudipati 
3524a36c61f9SKrishna Gudipati 	switch (event) {
3525a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3526a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
3527a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rft_id(ns, NULL);
3528a36c61f9SKrishna Gudipati 		break;
3529a36c61f9SKrishna Gudipati 
3530a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3531a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3532a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3533a36c61f9SKrishna Gudipati 		break;
3534a36c61f9SKrishna Gudipati 
3535a36c61f9SKrishna Gudipati 	default:
3536a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3537a36c61f9SKrishna Gudipati 	}
3538a36c61f9SKrishna Gudipati }
3539a36c61f9SKrishna Gudipati 
3540a36c61f9SKrishna Gudipati static void
3541a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns,
3542a36c61f9SKrishna Gudipati 				  enum vport_ns_event event)
3543a36c61f9SKrishna Gudipati {
3544a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3545a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3546a36c61f9SKrishna Gudipati 
3547a36c61f9SKrishna Gudipati 	switch (event) {
3548a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RFFID_SENT:
3549a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id);
3550a36c61f9SKrishna Gudipati 		break;
3551a36c61f9SKrishna Gudipati 
3552a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3553a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3554a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3555a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3556a36c61f9SKrishna Gudipati 		break;
3557a36c61f9SKrishna Gudipati 
3558a36c61f9SKrishna Gudipati 	default:
3559a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3560a36c61f9SKrishna Gudipati 	}
3561a36c61f9SKrishna Gudipati }
3562a36c61f9SKrishna Gudipati 
3563a36c61f9SKrishna Gudipati static void
3564a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3565a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3566a36c61f9SKrishna Gudipati {
3567a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3568a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3569a36c61f9SKrishna Gudipati 
3570a36c61f9SKrishna Gudipati 	switch (event) {
3571a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3572a36c61f9SKrishna Gudipati 
3573a36c61f9SKrishna Gudipati 		/*
3574a36c61f9SKrishna Gudipati 		 * If min cfg mode is enabled, we donot initiate rport
3575a36c61f9SKrishna Gudipati 		 * discovery with the fabric. Instead, we will retrieve the
3576a36c61f9SKrishna Gudipati 		 * boot targets from HAL/FW.
3577a36c61f9SKrishna Gudipati 		 */
3578a36c61f9SKrishna Gudipati 		if (__fcs_min_cfg(ns->port->fcs)) {
3579a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ns_boot_target_disc(ns->port);
3580a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
3581a36c61f9SKrishna Gudipati 			return;
3582a36c61f9SKrishna Gudipati 		}
3583a36c61f9SKrishna Gudipati 
3584a36c61f9SKrishna Gudipati 		/*
3585a36c61f9SKrishna Gudipati 		 * If the port role is Initiator Mode issue NS query.
3586a36c61f9SKrishna Gudipati 		 * If it is Target Mode, skip this and go to online.
3587a36c61f9SKrishna Gudipati 		 */
3588a36c61f9SKrishna Gudipati 		if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
3589a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ns,
3590a36c61f9SKrishna Gudipati 				bfa_fcs_lport_ns_sm_sending_gid_ft);
3591a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3592a36c61f9SKrishna Gudipati 		}
3593a36c61f9SKrishna Gudipati 		/*
3594a36c61f9SKrishna Gudipati 		 * kick off mgmt srvr state machine
3595a36c61f9SKrishna Gudipati 		 */
3596a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_online(ns->port);
3597a36c61f9SKrishna Gudipati 		break;
3598a36c61f9SKrishna Gudipati 
3599a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3600a36c61f9SKrishna Gudipati 		/*
3601a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3602a36c61f9SKrishna Gudipati 		 */
3603a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry);
3604a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3605a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3606a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3607a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3608a36c61f9SKrishna Gudipati 		break;
3609a36c61f9SKrishna Gudipati 
3610a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3611a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3612a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3613a36c61f9SKrishna Gudipati 		break;
3614a36c61f9SKrishna Gudipati 
3615a36c61f9SKrishna Gudipati 	default:
3616a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3617a36c61f9SKrishna Gudipati 	}
3618a36c61f9SKrishna Gudipati }
3619a36c61f9SKrishna Gudipati 
3620a36c61f9SKrishna Gudipati static void
3621a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3622a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3623a36c61f9SKrishna Gudipati {
3624a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3625a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3626a36c61f9SKrishna Gudipati 
3627a36c61f9SKrishna Gudipati 	switch (event) {
3628a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3629a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
3630a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rff_id(ns, NULL);
3631a36c61f9SKrishna Gudipati 		break;
3632a36c61f9SKrishna Gudipati 
3633a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3634a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3635a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3636a36c61f9SKrishna Gudipati 		break;
3637a36c61f9SKrishna Gudipati 
3638a36c61f9SKrishna Gudipati 	default:
3639a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3640a36c61f9SKrishna Gudipati 	}
3641a36c61f9SKrishna Gudipati }
3642a36c61f9SKrishna Gudipati static void
3643a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3644a36c61f9SKrishna Gudipati 				  enum vport_ns_event event)
3645a36c61f9SKrishna Gudipati {
3646a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3647a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3648a36c61f9SKrishna Gudipati 
3649a36c61f9SKrishna Gudipati 	switch (event) {
3650a36c61f9SKrishna Gudipati 	case NSSM_EVENT_GIDFT_SENT:
3651a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft);
3652a36c61f9SKrishna Gudipati 		break;
3653a36c61f9SKrishna Gudipati 
3654a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3655a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3656a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3657a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3658a36c61f9SKrishna Gudipati 		break;
3659a36c61f9SKrishna Gudipati 
3660a36c61f9SKrishna Gudipati 	default:
3661a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3662a36c61f9SKrishna Gudipati 	}
3663a36c61f9SKrishna Gudipati }
3664a36c61f9SKrishna Gudipati 
3665a36c61f9SKrishna Gudipati static void
3666a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3667a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3668a36c61f9SKrishna Gudipati {
3669a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3670a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3671a36c61f9SKrishna Gudipati 
3672a36c61f9SKrishna Gudipati 	switch (event) {
3673a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3674a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
3675a36c61f9SKrishna Gudipati 		break;
3676a36c61f9SKrishna Gudipati 
3677a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3678a36c61f9SKrishna Gudipati 		/*
3679a36c61f9SKrishna Gudipati 		 * TBD: for certain reject codes, we don't need to retry
3680a36c61f9SKrishna Gudipati 		 */
3681a36c61f9SKrishna Gudipati 		/*
3682a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3683a36c61f9SKrishna Gudipati 		 */
3684a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry);
3685a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3686a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3687a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3688a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3689a36c61f9SKrishna Gudipati 		break;
3690a36c61f9SKrishna Gudipati 
3691a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3692a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3693a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3694a36c61f9SKrishna Gudipati 		break;
3695a36c61f9SKrishna Gudipati 
3696a36c61f9SKrishna Gudipati 	case  NSSM_EVENT_NS_QUERY:
3697a36c61f9SKrishna Gudipati 		break;
3698a36c61f9SKrishna Gudipati 
3699a36c61f9SKrishna Gudipati 	default:
3700a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3701a36c61f9SKrishna Gudipati 	}
3702a36c61f9SKrishna Gudipati }
3703a36c61f9SKrishna Gudipati 
3704a36c61f9SKrishna Gudipati static void
3705a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3706a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3707a36c61f9SKrishna Gudipati {
3708a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3709a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3710a36c61f9SKrishna Gudipati 
3711a36c61f9SKrishna Gudipati 	switch (event) {
3712a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3713a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft);
3714a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3715a36c61f9SKrishna Gudipati 		break;
3716a36c61f9SKrishna Gudipati 
3717a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3718a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3719a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3720a36c61f9SKrishna Gudipati 		break;
3721a36c61f9SKrishna Gudipati 
3722a36c61f9SKrishna Gudipati 	default:
3723a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3724a36c61f9SKrishna Gudipati 	}
3725a36c61f9SKrishna Gudipati }
3726a36c61f9SKrishna Gudipati 
3727a36c61f9SKrishna Gudipati static void
3728a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3729a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3730a36c61f9SKrishna Gudipati {
3731a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3732a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3733a36c61f9SKrishna Gudipati 
3734a36c61f9SKrishna Gudipati 	switch (event) {
3735a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3736a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3737a36c61f9SKrishna Gudipati 		break;
3738a36c61f9SKrishna Gudipati 
3739a36c61f9SKrishna Gudipati 	case NSSM_EVENT_NS_QUERY:
3740a36c61f9SKrishna Gudipati 		/*
3741a36c61f9SKrishna Gudipati 		 * If the port role is Initiator Mode issue NS query.
3742a36c61f9SKrishna Gudipati 		 * If it is Target Mode, skip this and go to online.
3743a36c61f9SKrishna Gudipati 		 */
3744a36c61f9SKrishna Gudipati 		if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
3745a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ns,
3746a36c61f9SKrishna Gudipati 				bfa_fcs_lport_ns_sm_sending_gid_ft);
3747a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3748a36c61f9SKrishna Gudipati 		};
3749a36c61f9SKrishna Gudipati 		break;
3750a36c61f9SKrishna Gudipati 
3751a36c61f9SKrishna Gudipati 	default:
3752a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3753a36c61f9SKrishna Gudipati 	}
3754a36c61f9SKrishna Gudipati }
3755a36c61f9SKrishna Gudipati 
3756a36c61f9SKrishna Gudipati 
3757a36c61f9SKrishna Gudipati 
37585fbe25c7SJing Huang /*
3759a36c61f9SKrishna Gudipati  *  ns_pvt Nameserver local functions
3760a36c61f9SKrishna Gudipati  */
3761a36c61f9SKrishna Gudipati 
3762a36c61f9SKrishna Gudipati static void
3763a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3764a36c61f9SKrishna Gudipati {
3765a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3766a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
3767a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
3768a36c61f9SKrishna Gudipati 	int             len;
3769a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3770a36c61f9SKrishna Gudipati 
3771a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
3772a36c61f9SKrishna Gudipati 
3773a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3774a36c61f9SKrishna Gudipati 	if (!fcxp) {
3775a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_alloc_wait++;
3776a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3777a36c61f9SKrishna Gudipati 					bfa_fcs_lport_ns_send_plogi, ns);
3778a36c61f9SKrishna Gudipati 		return;
3779a36c61f9SKrishna Gudipati 	}
3780a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
3781a36c61f9SKrishna Gudipati 
3782a36c61f9SKrishna Gudipati 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3783f16a1750SMaggie Zhang 			     bfa_hton3b(FC_NAME_SERVER),
3784a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port), 0,
3785a36c61f9SKrishna Gudipati 			     port->port_cfg.pwwn, port->port_cfg.nwwn,
3786be540a99SKrishna Gudipati 			     bfa_fcport_get_maxfrsize(port->fcs->bfa),
3787be540a99SKrishna Gudipati 			     bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
3788a36c61f9SKrishna Gudipati 
3789a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3790a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3791a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_plogi_response, (void *)ns,
3792a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_ELS_TOV);
3793a36c61f9SKrishna Gudipati 	port->stats.ns_plogi_sent++;
3794a36c61f9SKrishna Gudipati 
3795a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
3796a36c61f9SKrishna Gudipati }
3797a36c61f9SKrishna Gudipati 
3798a36c61f9SKrishna Gudipati static void
3799a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3800a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
3801a36c61f9SKrishna Gudipati 		       u32 resid_len, struct fchs_s *rsp_fchs)
3802a36c61f9SKrishna Gudipati {
3803a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3804a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
3805a36c61f9SKrishna Gudipati 	/* struct fc_logi_s *plogi_resp; */
3806a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd;
3807a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
3808a36c61f9SKrishna Gudipati 
3809a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
3810a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3811a36c61f9SKrishna Gudipati 
3812a36c61f9SKrishna Gudipati 	/*
3813a36c61f9SKrishna Gudipati 	 * Sanity Checks
3814a36c61f9SKrishna Gudipati 	 */
3815a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3816a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
3817a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_rsp_err++;
3818a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3819a36c61f9SKrishna Gudipati 		return;
3820a36c61f9SKrishna Gudipati 	}
3821a36c61f9SKrishna Gudipati 
3822a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
3823a36c61f9SKrishna Gudipati 
3824a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
3825a36c61f9SKrishna Gudipati 
3826a36c61f9SKrishna Gudipati 	case FC_ELS_ACC:
3827a36c61f9SKrishna Gudipati 		if (rsp_len < sizeof(struct fc_logi_s)) {
3828a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rsp_len);
3829a36c61f9SKrishna Gudipati 			port->stats.ns_plogi_acc_err++;
3830a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3831a36c61f9SKrishna Gudipati 			break;
3832a36c61f9SKrishna Gudipati 		}
3833a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_accepts++;
3834a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3835a36c61f9SKrishna Gudipati 		break;
3836a36c61f9SKrishna Gudipati 
3837a36c61f9SKrishna Gudipati 	case FC_ELS_LS_RJT:
3838a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3839a36c61f9SKrishna Gudipati 
3840a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code);
3841a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code_expl);
3842a36c61f9SKrishna Gudipati 
3843a36c61f9SKrishna Gudipati 		port->stats.ns_rejects++;
3844a36c61f9SKrishna Gudipati 
3845a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3846a36c61f9SKrishna Gudipati 		break;
3847a36c61f9SKrishna Gudipati 
3848a36c61f9SKrishna Gudipati 	default:
3849a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_unknown_rsp++;
3850a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, els_cmd->els_code);
3851a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3852a36c61f9SKrishna Gudipati 	}
3853a36c61f9SKrishna Gudipati }
3854a36c61f9SKrishna Gudipati 
38555fbe25c7SJing Huang /*
3856a36c61f9SKrishna Gudipati  * Register the symbolic port name.
3857a36c61f9SKrishna Gudipati  */
3858a36c61f9SKrishna Gudipati static void
3859a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3860a36c61f9SKrishna Gudipati {
3861a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3862a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
3863a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
3864a36c61f9SKrishna Gudipati 	int             len;
3865a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3866a36c61f9SKrishna Gudipati 	u8         symbl[256];
3867a36c61f9SKrishna Gudipati 	u8         *psymbl = &symbl[0];
3868a36c61f9SKrishna Gudipati 
38696a18b167SJing Huang 	memset(symbl, 0, sizeof(symbl));
3870a36c61f9SKrishna Gudipati 
3871a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3872a36c61f9SKrishna Gudipati 
3873a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3874a36c61f9SKrishna Gudipati 	if (!fcxp) {
3875a36c61f9SKrishna Gudipati 		port->stats.ns_rspnid_alloc_wait++;
3876a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3877a36c61f9SKrishna Gudipati 					bfa_fcs_lport_ns_send_rspn_id, ns);
3878a36c61f9SKrishna Gudipati 		return;
3879a36c61f9SKrishna Gudipati 	}
3880a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
3881a36c61f9SKrishna Gudipati 
3882a36c61f9SKrishna Gudipati 	/*
3883a36c61f9SKrishna Gudipati 	 * for V-Port, form a Port Symbolic Name
3884a36c61f9SKrishna Gudipati 	 */
3885a36c61f9SKrishna Gudipati 	if (port->vport) {
38865fbe25c7SJing Huang 		/*
3887a36c61f9SKrishna Gudipati 		 * For Vports, we append the vport's port symbolic name
3888a36c61f9SKrishna Gudipati 		 * to that of the base port.
3889a36c61f9SKrishna Gudipati 		 */
3890a36c61f9SKrishna Gudipati 
3891a36c61f9SKrishna Gudipati 		strncpy((char *)psymbl,
3892a36c61f9SKrishna Gudipati 			(char *) &
3893a36c61f9SKrishna Gudipati 			(bfa_fcs_lport_get_psym_name
3894a36c61f9SKrishna Gudipati 			 (bfa_fcs_get_base_port(port->fcs))),
3895a36c61f9SKrishna Gudipati 			strlen((char *) &
3896a36c61f9SKrishna Gudipati 			       bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3897a36c61f9SKrishna Gudipati 							  (port->fcs))));
3898a36c61f9SKrishna Gudipati 
3899a36c61f9SKrishna Gudipati 		/* Ensure we have a null terminating string. */
3900a36c61f9SKrishna Gudipati 		((char *)psymbl)[strlen((char *) &
3901a36c61f9SKrishna Gudipati 			bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3902a36c61f9SKrishna Gudipati 						(port->fcs)))] = 0;
3903a36c61f9SKrishna Gudipati 		strncat((char *)psymbl,
3904a36c61f9SKrishna Gudipati 			(char *) &(bfa_fcs_lport_get_psym_name(port)),
3905a36c61f9SKrishna Gudipati 		strlen((char *) &bfa_fcs_lport_get_psym_name(port)));
3906a36c61f9SKrishna Gudipati 	} else {
3907a36c61f9SKrishna Gudipati 		psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port));
3908a36c61f9SKrishna Gudipati 	}
3909a36c61f9SKrishna Gudipati 
3910a36c61f9SKrishna Gudipati 	len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3911a36c61f9SKrishna Gudipati 			      bfa_fcs_lport_get_fcid(port), 0, psymbl);
3912a36c61f9SKrishna Gudipati 
3913a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3914a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3915a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_rspn_id_response, (void *)ns,
3916a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
3917a36c61f9SKrishna Gudipati 
3918a36c61f9SKrishna Gudipati 	port->stats.ns_rspnid_sent++;
3919a36c61f9SKrishna Gudipati 
3920a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
3921a36c61f9SKrishna Gudipati }
3922a36c61f9SKrishna Gudipati 
3923a36c61f9SKrishna Gudipati static void
3924a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3925a36c61f9SKrishna Gudipati 				 void *cbarg, bfa_status_t req_status,
3926a36c61f9SKrishna Gudipati 				 u32 rsp_len, u32 resid_len,
3927a36c61f9SKrishna Gudipati 				 struct fchs_s *rsp_fchs)
3928a36c61f9SKrishna Gudipati {
3929a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3930a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
3931a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
3932a36c61f9SKrishna Gudipati 
3933a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3934a36c61f9SKrishna Gudipati 
3935a36c61f9SKrishna Gudipati 	/*
3936a36c61f9SKrishna Gudipati 	 * Sanity Checks
3937a36c61f9SKrishna Gudipati 	 */
3938a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3939a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
3940a36c61f9SKrishna Gudipati 		port->stats.ns_rspnid_rsp_err++;
3941a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3942a36c61f9SKrishna Gudipati 		return;
3943a36c61f9SKrishna Gudipati 	}
3944a36c61f9SKrishna Gudipati 
3945a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3946ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3947a36c61f9SKrishna Gudipati 
3948a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3949a36c61f9SKrishna Gudipati 		port->stats.ns_rspnid_accepts++;
3950a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3951a36c61f9SKrishna Gudipati 		return;
3952a36c61f9SKrishna Gudipati 	}
3953a36c61f9SKrishna Gudipati 
3954a36c61f9SKrishna Gudipati 	port->stats.ns_rspnid_rejects++;
3955a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
3956a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
3957a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3958a36c61f9SKrishna Gudipati }
3959a36c61f9SKrishna Gudipati 
39605fbe25c7SJing Huang /*
3961a36c61f9SKrishna Gudipati  * Register FC4-Types
3962a36c61f9SKrishna Gudipati  */
3963a36c61f9SKrishna Gudipati static void
3964a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3965a36c61f9SKrishna Gudipati {
3966a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3967a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
3968a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
3969a36c61f9SKrishna Gudipati 	int             len;
3970a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3971a36c61f9SKrishna Gudipati 
3972a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3973a36c61f9SKrishna Gudipati 
3974a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3975a36c61f9SKrishna Gudipati 	if (!fcxp) {
3976a36c61f9SKrishna Gudipati 		port->stats.ns_rftid_alloc_wait++;
3977a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3978a36c61f9SKrishna Gudipati 					bfa_fcs_lport_ns_send_rft_id, ns);
3979a36c61f9SKrishna Gudipati 		return;
3980a36c61f9SKrishna Gudipati 	}
3981a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
3982a36c61f9SKrishna Gudipati 
3983a36c61f9SKrishna Gudipati 	len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3984a36c61f9SKrishna Gudipati 		     bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles);
3985a36c61f9SKrishna Gudipati 
3986a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3987a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3988a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_rft_id_response, (void *)ns,
3989a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
3990a36c61f9SKrishna Gudipati 
3991a36c61f9SKrishna Gudipati 	port->stats.ns_rftid_sent++;
3992a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
3993a36c61f9SKrishna Gudipati }
3994a36c61f9SKrishna Gudipati 
3995a36c61f9SKrishna Gudipati static void
3996a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3997a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
3998a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
3999a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4000a36c61f9SKrishna Gudipati {
4001a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4002a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4003a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
4004a36c61f9SKrishna Gudipati 
4005a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4006a36c61f9SKrishna Gudipati 
4007a36c61f9SKrishna Gudipati 	/*
4008a36c61f9SKrishna Gudipati 	 * Sanity Checks
4009a36c61f9SKrishna Gudipati 	 */
4010a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4011a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4012a36c61f9SKrishna Gudipati 		port->stats.ns_rftid_rsp_err++;
4013a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4014a36c61f9SKrishna Gudipati 		return;
4015a36c61f9SKrishna Gudipati 	}
4016a36c61f9SKrishna Gudipati 
4017a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4018ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4019a36c61f9SKrishna Gudipati 
4020a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4021a36c61f9SKrishna Gudipati 		port->stats.ns_rftid_accepts++;
4022a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4023a36c61f9SKrishna Gudipati 		return;
4024a36c61f9SKrishna Gudipati 	}
4025a36c61f9SKrishna Gudipati 
4026a36c61f9SKrishna Gudipati 	port->stats.ns_rftid_rejects++;
4027a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
4028a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
4029a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4030a36c61f9SKrishna Gudipati }
4031a36c61f9SKrishna Gudipati 
40325fbe25c7SJing Huang /*
4033a36c61f9SKrishna Gudipati  * Register FC4-Features : Should be done after RFT_ID
4034a36c61f9SKrishna Gudipati  */
4035a36c61f9SKrishna Gudipati static void
4036a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4037a36c61f9SKrishna Gudipati {
4038a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4039a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4040a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4041a36c61f9SKrishna Gudipati 	int             len;
4042a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4043a36c61f9SKrishna Gudipati 	u8			fc4_ftrs = 0;
4044a36c61f9SKrishna Gudipati 
4045a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4046a36c61f9SKrishna Gudipati 
4047a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
4048a36c61f9SKrishna Gudipati 	if (!fcxp) {
4049a36c61f9SKrishna Gudipati 		port->stats.ns_rffid_alloc_wait++;
4050a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4051a36c61f9SKrishna Gudipati 					bfa_fcs_lport_ns_send_rff_id, ns);
4052a36c61f9SKrishna Gudipati 		return;
4053a36c61f9SKrishna Gudipati 	}
4054a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
4055a36c61f9SKrishna Gudipati 
4056a36c61f9SKrishna Gudipati 	if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port))
4057a36c61f9SKrishna Gudipati 		fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
4058a36c61f9SKrishna Gudipati 
4059a36c61f9SKrishna Gudipati 	len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4060a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port), 0,
4061a36c61f9SKrishna Gudipati 				 FC_TYPE_FCP, fc4_ftrs);
4062a36c61f9SKrishna Gudipati 
4063a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4064a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4065a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_rff_id_response, (void *)ns,
4066a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
4067a36c61f9SKrishna Gudipati 
4068a36c61f9SKrishna Gudipati 	port->stats.ns_rffid_sent++;
4069a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
4070a36c61f9SKrishna Gudipati }
4071a36c61f9SKrishna Gudipati 
4072a36c61f9SKrishna Gudipati static void
4073a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4074a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
4075a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
4076a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4077a36c61f9SKrishna Gudipati {
4078a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4079a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4080a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
4081a36c61f9SKrishna Gudipati 
4082a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4083a36c61f9SKrishna Gudipati 
4084a36c61f9SKrishna Gudipati 	/*
4085a36c61f9SKrishna Gudipati 	 * Sanity Checks
4086a36c61f9SKrishna Gudipati 	 */
4087a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4088a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4089a36c61f9SKrishna Gudipati 		port->stats.ns_rffid_rsp_err++;
4090a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4091a36c61f9SKrishna Gudipati 		return;
4092a36c61f9SKrishna Gudipati 	}
4093a36c61f9SKrishna Gudipati 
4094a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4095ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4096a36c61f9SKrishna Gudipati 
4097a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4098a36c61f9SKrishna Gudipati 		port->stats.ns_rffid_accepts++;
4099a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4100a36c61f9SKrishna Gudipati 		return;
4101a36c61f9SKrishna Gudipati 	}
4102a36c61f9SKrishna Gudipati 
4103a36c61f9SKrishna Gudipati 	port->stats.ns_rffid_rejects++;
4104a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
4105a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
4106a36c61f9SKrishna Gudipati 
4107a36c61f9SKrishna Gudipati 	if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
4108a36c61f9SKrishna Gudipati 		/* if this command is not supported, we don't retry */
4109a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4110a36c61f9SKrishna Gudipati 	} else
4111a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4112a36c61f9SKrishna Gudipati }
41135fbe25c7SJing Huang /*
4114a36c61f9SKrishna Gudipati  * Query Fabric for FC4-Types Devices.
4115a36c61f9SKrishna Gudipati  *
4116a36c61f9SKrishna Gudipati * TBD : Need to use a local (FCS private) response buffer, since the response
4117a36c61f9SKrishna Gudipati  * can be larger than 2K.
4118a36c61f9SKrishna Gudipati  */
4119a36c61f9SKrishna Gudipati static void
4120a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4121a36c61f9SKrishna Gudipati {
4122a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4123a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4124a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4125a36c61f9SKrishna Gudipati 	int             len;
4126a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4127a36c61f9SKrishna Gudipati 
4128a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
4129a36c61f9SKrishna Gudipati 
4130a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
4131a36c61f9SKrishna Gudipati 	if (!fcxp) {
4132a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_alloc_wait++;
4133a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4134a36c61f9SKrishna Gudipati 					bfa_fcs_lport_ns_send_gid_ft, ns);
4135a36c61f9SKrishna Gudipati 		return;
4136a36c61f9SKrishna Gudipati 	}
4137a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
4138a36c61f9SKrishna Gudipati 
4139a36c61f9SKrishna Gudipati 	/*
4140a36c61f9SKrishna Gudipati 	 * This query is only initiated for FCP initiator mode.
4141a36c61f9SKrishna Gudipati 	 */
4142a36c61f9SKrishna Gudipati 	len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4143a36c61f9SKrishna Gudipati 			      ns->port->pid, FC_TYPE_FCP);
4144a36c61f9SKrishna Gudipati 
4145a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4146a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4147a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_gid_ft_response, (void *)ns,
4148a36c61f9SKrishna Gudipati 			  bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV);
4149a36c61f9SKrishna Gudipati 
4150a36c61f9SKrishna Gudipati 	port->stats.ns_gidft_sent++;
4151a36c61f9SKrishna Gudipati 
4152a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
4153a36c61f9SKrishna Gudipati }
4154a36c61f9SKrishna Gudipati 
4155a36c61f9SKrishna Gudipati static void
4156a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4157a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
4158a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
4159a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4160a36c61f9SKrishna Gudipati {
4161a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4162a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4163a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
4164a36c61f9SKrishna Gudipati 	u32        n_pids;
4165a36c61f9SKrishna Gudipati 
4166a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4167a36c61f9SKrishna Gudipati 
4168a36c61f9SKrishna Gudipati 	/*
4169a36c61f9SKrishna Gudipati 	 * Sanity Checks
4170a36c61f9SKrishna Gudipati 	 */
4171a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4172a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4173a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_rsp_err++;
4174a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4175a36c61f9SKrishna Gudipati 		return;
4176a36c61f9SKrishna Gudipati 	}
4177a36c61f9SKrishna Gudipati 
4178a36c61f9SKrishna Gudipati 	if (resid_len != 0) {
4179a36c61f9SKrishna Gudipati 		/*
4180a36c61f9SKrishna Gudipati 		 * TBD : we will need to allocate a larger buffer & retry the
4181a36c61f9SKrishna Gudipati 		 * command
4182a36c61f9SKrishna Gudipati 		 */
4183a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rsp_len);
4184a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, resid_len);
4185a36c61f9SKrishna Gudipati 		return;
4186a36c61f9SKrishna Gudipati 	}
4187a36c61f9SKrishna Gudipati 
4188a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4189ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4190a36c61f9SKrishna Gudipati 
4191a36c61f9SKrishna Gudipati 	switch (cthdr->cmd_rsp_code) {
4192a36c61f9SKrishna Gudipati 
4193a36c61f9SKrishna Gudipati 	case CT_RSP_ACCEPT:
4194a36c61f9SKrishna Gudipati 
4195a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_accepts++;
4196a36c61f9SKrishna Gudipati 		n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
4197a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, n_pids);
4198a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_process_gidft_pids(port,
4199a36c61f9SKrishna Gudipati 						   (u32 *) (cthdr + 1),
4200a36c61f9SKrishna Gudipati 						   n_pids);
4201a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4202a36c61f9SKrishna Gudipati 		break;
4203a36c61f9SKrishna Gudipati 
4204a36c61f9SKrishna Gudipati 	case CT_RSP_REJECT:
4205a36c61f9SKrishna Gudipati 
4206a36c61f9SKrishna Gudipati 		/*
4207a36c61f9SKrishna Gudipati 		 * Check the reason code  & explanation.
4208a36c61f9SKrishna Gudipati 		 * There may not have been any FC4 devices in the fabric
4209a36c61f9SKrishna Gudipati 		 */
4210a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_rejects++;
4211a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, cthdr->reason_code);
4212a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, cthdr->exp_code);
4213a36c61f9SKrishna Gudipati 
4214a36c61f9SKrishna Gudipati 		if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
4215a36c61f9SKrishna Gudipati 		    && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
4216a36c61f9SKrishna Gudipati 
4217a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4218a36c61f9SKrishna Gudipati 		} else {
4219a36c61f9SKrishna Gudipati 			/*
4220a36c61f9SKrishna Gudipati 			 * for all other errors, retry
4221a36c61f9SKrishna Gudipati 			 */
4222a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4223a36c61f9SKrishna Gudipati 		}
4224a36c61f9SKrishna Gudipati 		break;
4225a36c61f9SKrishna Gudipati 
4226a36c61f9SKrishna Gudipati 	default:
4227a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_unknown_rsp++;
4228a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, cthdr->cmd_rsp_code);
4229a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4230a36c61f9SKrishna Gudipati 	}
4231a36c61f9SKrishna Gudipati }
4232a36c61f9SKrishna Gudipati 
42335fbe25c7SJing Huang /*
4234a36c61f9SKrishna Gudipati  *     This routine will be called by bfa_timer on timer timeouts.
4235a36c61f9SKrishna Gudipati  *
4236a36c61f9SKrishna Gudipati  *	param[in]	port - pointer to bfa_fcs_lport_t.
4237a36c61f9SKrishna Gudipati  *
4238a36c61f9SKrishna Gudipati  *	return
4239a36c61f9SKrishna Gudipati  *		void
4240a36c61f9SKrishna Gudipati  *
4241a36c61f9SKrishna Gudipati  *	Special Considerations:
4242a36c61f9SKrishna Gudipati  *
4243a36c61f9SKrishna Gudipati  *	note
4244a36c61f9SKrishna Gudipati  */
4245a36c61f9SKrishna Gudipati static void
4246a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_timeout(void *arg)
4247a36c61f9SKrishna Gudipati {
4248a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg;
4249a36c61f9SKrishna Gudipati 
4250a36c61f9SKrishna Gudipati 	ns->port->stats.ns_timeouts++;
4251a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
4252a36c61f9SKrishna Gudipati }
4253a36c61f9SKrishna Gudipati 
4254a36c61f9SKrishna Gudipati /*
4255a36c61f9SKrishna Gudipati  * Process the PID list in GID_FT response
4256a36c61f9SKrishna Gudipati  */
4257a36c61f9SKrishna Gudipati static void
4258a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf,
4259a36c61f9SKrishna Gudipati 				   u32 n_pids)
4260a36c61f9SKrishna Gudipati {
4261a36c61f9SKrishna Gudipati 	struct fcgs_gidft_resp_s *gidft_entry;
4262a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
4263a36c61f9SKrishna Gudipati 	u32        ii;
4264a36c61f9SKrishna Gudipati 
4265a36c61f9SKrishna Gudipati 	for (ii = 0; ii < n_pids; ii++) {
4266a36c61f9SKrishna Gudipati 		gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
4267a36c61f9SKrishna Gudipati 
4268a36c61f9SKrishna Gudipati 		if (gidft_entry->pid == port->pid)
4269a36c61f9SKrishna Gudipati 			continue;
4270a36c61f9SKrishna Gudipati 
4271a36c61f9SKrishna Gudipati 		/*
4272a36c61f9SKrishna Gudipati 		 * Check if this rport already exists
4273a36c61f9SKrishna Gudipati 		 */
4274a36c61f9SKrishna Gudipati 		rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid);
4275a36c61f9SKrishna Gudipati 		if (rport == NULL) {
4276a36c61f9SKrishna Gudipati 			/*
4277a36c61f9SKrishna Gudipati 			 * this is a new device. create rport
4278a36c61f9SKrishna Gudipati 			 */
4279a36c61f9SKrishna Gudipati 			rport = bfa_fcs_rport_create(port, gidft_entry->pid);
4280a36c61f9SKrishna Gudipati 		} else {
4281a36c61f9SKrishna Gudipati 			/*
4282a36c61f9SKrishna Gudipati 			 * this rport already exists
4283a36c61f9SKrishna Gudipati 			 */
4284a36c61f9SKrishna Gudipati 			bfa_fcs_rport_scn(rport);
4285a36c61f9SKrishna Gudipati 		}
4286a36c61f9SKrishna Gudipati 
4287a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, gidft_entry->pid);
4288a36c61f9SKrishna Gudipati 
4289a36c61f9SKrishna Gudipati 		/*
4290a36c61f9SKrishna Gudipati 		 * if the last entry bit is set, bail out.
4291a36c61f9SKrishna Gudipati 		 */
4292a36c61f9SKrishna Gudipati 		if (gidft_entry->last)
4293a36c61f9SKrishna Gudipati 			return;
4294a36c61f9SKrishna Gudipati 	}
4295a36c61f9SKrishna Gudipati }
4296a36c61f9SKrishna Gudipati 
42975fbe25c7SJing Huang /*
4298a36c61f9SKrishna Gudipati  *  fcs_ns_public FCS nameserver public interfaces
4299a36c61f9SKrishna Gudipati  */
4300a36c61f9SKrishna Gudipati 
4301a36c61f9SKrishna Gudipati /*
4302a36c61f9SKrishna Gudipati  * Functions called by port/fab.
4303a36c61f9SKrishna Gudipati  * These will send relevant Events to the ns state machine.
4304a36c61f9SKrishna Gudipati  */
4305a36c61f9SKrishna Gudipati void
4306a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port)
4307a36c61f9SKrishna Gudipati {
4308a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4309a36c61f9SKrishna Gudipati 
4310a36c61f9SKrishna Gudipati 	ns->port = port;
4311a36c61f9SKrishna Gudipati 	bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4312a36c61f9SKrishna Gudipati }
4313a36c61f9SKrishna Gudipati 
4314a36c61f9SKrishna Gudipati void
4315a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port)
4316a36c61f9SKrishna Gudipati {
4317a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4318a36c61f9SKrishna Gudipati 
4319a36c61f9SKrishna Gudipati 	ns->port = port;
4320a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
4321a36c61f9SKrishna Gudipati }
4322a36c61f9SKrishna Gudipati 
4323a36c61f9SKrishna Gudipati void
4324a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port)
4325a36c61f9SKrishna Gudipati {
4326a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4327a36c61f9SKrishna Gudipati 
4328a36c61f9SKrishna Gudipati 	ns->port = port;
4329a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
4330a36c61f9SKrishna Gudipati }
4331a36c61f9SKrishna Gudipati 
4332a36c61f9SKrishna Gudipati void
4333a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port)
4334a36c61f9SKrishna Gudipati {
4335a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4336a36c61f9SKrishna Gudipati 
4337a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
4338a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
4339a36c61f9SKrishna Gudipati }
4340a36c61f9SKrishna Gudipati 
434152f94b6fSMaggie static void
4342a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
4343a36c61f9SKrishna Gudipati {
4344a36c61f9SKrishna Gudipati 
4345a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
4346a36c61f9SKrishna Gudipati 	u8 nwwns;
4347a36c61f9SKrishna Gudipati 	wwn_t  wwns[BFA_PREBOOT_BOOTLUN_MAX];
4348a36c61f9SKrishna Gudipati 	int ii;
4349a36c61f9SKrishna Gudipati 
4350a36c61f9SKrishna Gudipati 	bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns);
4351a36c61f9SKrishna Gudipati 
4352a36c61f9SKrishna Gudipati 	for (ii = 0 ; ii < nwwns; ++ii) {
4353a36c61f9SKrishna Gudipati 		rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
4354d4b671c5SJing Huang 		WARN_ON(!rport);
4355a36c61f9SKrishna Gudipati 	}
4356a36c61f9SKrishna Gudipati }
4357a36c61f9SKrishna Gudipati 
43585fbe25c7SJing Huang /*
4359a36c61f9SKrishna Gudipati  * FCS SCN
4360a36c61f9SKrishna Gudipati  */
4361a36c61f9SKrishna Gudipati 
4362a36c61f9SKrishna Gudipati #define FC_QOS_RSCN_EVENT		0x0c
4363a36c61f9SKrishna Gudipati #define FC_FABRIC_NAME_RSCN_EVENT	0x0d
4364a36c61f9SKrishna Gudipati 
4365a36c61f9SKrishna Gudipati /*
4366a36c61f9SKrishna Gudipati  * forward declarations
4367a36c61f9SKrishna Gudipati  */
4368a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_send_scr(void *scn_cbarg,
4369a36c61f9SKrishna Gudipati 					  struct bfa_fcxp_s *fcxp_alloced);
4370a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_scr_response(void *fcsarg,
4371a36c61f9SKrishna Gudipati 					      struct bfa_fcxp_s *fcxp,
4372a36c61f9SKrishna Gudipati 					      void *cbarg,
4373a36c61f9SKrishna Gudipati 					      bfa_status_t req_status,
4374a36c61f9SKrishna Gudipati 					      u32 rsp_len,
4375a36c61f9SKrishna Gudipati 					      u32 resid_len,
4376a36c61f9SKrishna Gudipati 					      struct fchs_s *rsp_fchs);
4377a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
4378a36c61f9SKrishna Gudipati 					     struct fchs_s *rx_fchs);
4379a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_timeout(void *arg);
4380a36c61f9SKrishna Gudipati 
43815fbe25c7SJing Huang /*
4382a36c61f9SKrishna Gudipati  *  fcs_scm_sm FCS SCN state machine
4383a36c61f9SKrishna Gudipati  */
4384a36c61f9SKrishna Gudipati 
43855fbe25c7SJing Huang /*
4386a36c61f9SKrishna Gudipati  * VPort SCN State Machine events
4387a36c61f9SKrishna Gudipati  */
4388a36c61f9SKrishna Gudipati enum port_scn_event {
4389a36c61f9SKrishna Gudipati 	SCNSM_EVENT_PORT_ONLINE = 1,
4390a36c61f9SKrishna Gudipati 	SCNSM_EVENT_PORT_OFFLINE = 2,
4391a36c61f9SKrishna Gudipati 	SCNSM_EVENT_RSP_OK = 3,
4392a36c61f9SKrishna Gudipati 	SCNSM_EVENT_RSP_ERROR = 4,
4393a36c61f9SKrishna Gudipati 	SCNSM_EVENT_TIMEOUT = 5,
4394a36c61f9SKrishna Gudipati 	SCNSM_EVENT_SCR_SENT = 6,
4395a36c61f9SKrishna Gudipati };
4396a36c61f9SKrishna Gudipati 
4397a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
4398a36c61f9SKrishna Gudipati 					    enum port_scn_event event);
4399a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_sending_scr(
4400a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_scn_s *scn,
4401a36c61f9SKrishna Gudipati 					enum port_scn_event event);
4402a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
4403a36c61f9SKrishna Gudipati 					enum port_scn_event event);
4404a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
4405a36c61f9SKrishna Gudipati 					      enum port_scn_event event);
4406a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
4407a36c61f9SKrishna Gudipati 					   enum port_scn_event event);
4408a36c61f9SKrishna Gudipati 
44095fbe25c7SJing Huang /*
4410a36c61f9SKrishna Gudipati  *	Starting state - awaiting link up.
4411a36c61f9SKrishna Gudipati  */
4412a36c61f9SKrishna Gudipati static void
4413a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
4414a36c61f9SKrishna Gudipati 			enum port_scn_event event)
4415a36c61f9SKrishna Gudipati {
4416a36c61f9SKrishna Gudipati 	switch (event) {
4417a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_ONLINE:
4418a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
4419a36c61f9SKrishna Gudipati 		bfa_fcs_lport_scn_send_scr(scn, NULL);
4420a36c61f9SKrishna Gudipati 		break;
4421a36c61f9SKrishna Gudipati 
4422a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
4423a36c61f9SKrishna Gudipati 		break;
4424a36c61f9SKrishna Gudipati 
4425a36c61f9SKrishna Gudipati 	default:
4426a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
4427a36c61f9SKrishna Gudipati 	}
4428a36c61f9SKrishna Gudipati }
4429a36c61f9SKrishna Gudipati 
4430a36c61f9SKrishna Gudipati static void
4431a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn,
4432a36c61f9SKrishna Gudipati 				enum port_scn_event event)
4433a36c61f9SKrishna Gudipati {
4434a36c61f9SKrishna Gudipati 	switch (event) {
4435a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_SCR_SENT:
4436a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr);
4437a36c61f9SKrishna Gudipati 		break;
4438a36c61f9SKrishna Gudipati 
4439a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
4440a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4441a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe);
4442a36c61f9SKrishna Gudipati 		break;
4443a36c61f9SKrishna Gudipati 
4444a36c61f9SKrishna Gudipati 	default:
4445a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
4446a36c61f9SKrishna Gudipati 	}
4447a36c61f9SKrishna Gudipati }
4448a36c61f9SKrishna Gudipati 
4449a36c61f9SKrishna Gudipati static void
4450a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
4451a36c61f9SKrishna Gudipati 			enum port_scn_event event)
4452a36c61f9SKrishna Gudipati {
4453a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = scn->port;
4454a36c61f9SKrishna Gudipati 
4455a36c61f9SKrishna Gudipati 	switch (event) {
4456a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_RSP_OK:
4457a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online);
4458a36c61f9SKrishna Gudipati 		break;
4459a36c61f9SKrishna Gudipati 
4460a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_RSP_ERROR:
4461a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry);
4462a36c61f9SKrishna Gudipati 		bfa_timer_start(port->fcs->bfa, &scn->timer,
4463a36c61f9SKrishna Gudipati 				    bfa_fcs_lport_scn_timeout, scn,
4464a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
4465a36c61f9SKrishna Gudipati 		break;
4466a36c61f9SKrishna Gudipati 
4467a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
4468a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4469a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(scn->fcxp);
4470a36c61f9SKrishna Gudipati 		break;
4471a36c61f9SKrishna Gudipati 
4472a36c61f9SKrishna Gudipati 	default:
4473a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
4474a36c61f9SKrishna Gudipati 	}
4475a36c61f9SKrishna Gudipati }
4476a36c61f9SKrishna Gudipati 
4477a36c61f9SKrishna Gudipati static void
4478a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
4479a36c61f9SKrishna Gudipati 				enum port_scn_event event)
4480a36c61f9SKrishna Gudipati {
4481a36c61f9SKrishna Gudipati 	switch (event) {
4482a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_TIMEOUT:
4483a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
4484a36c61f9SKrishna Gudipati 		bfa_fcs_lport_scn_send_scr(scn, NULL);
4485a36c61f9SKrishna Gudipati 		break;
4486a36c61f9SKrishna Gudipati 
4487a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
4488a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4489a36c61f9SKrishna Gudipati 		bfa_timer_stop(&scn->timer);
4490a36c61f9SKrishna Gudipati 		break;
4491a36c61f9SKrishna Gudipati 
4492a36c61f9SKrishna Gudipati 	default:
4493a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
4494a36c61f9SKrishna Gudipati 	}
4495a36c61f9SKrishna Gudipati }
4496a36c61f9SKrishna Gudipati 
4497a36c61f9SKrishna Gudipati static void
4498a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
4499a36c61f9SKrishna Gudipati 			enum port_scn_event event)
4500a36c61f9SKrishna Gudipati {
4501a36c61f9SKrishna Gudipati 	switch (event) {
4502a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
4503a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4504a36c61f9SKrishna Gudipati 		break;
4505a36c61f9SKrishna Gudipati 
4506a36c61f9SKrishna Gudipati 	default:
4507a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
4508a36c61f9SKrishna Gudipati 	}
4509a36c61f9SKrishna Gudipati }
4510a36c61f9SKrishna Gudipati 
4511a36c61f9SKrishna Gudipati 
4512a36c61f9SKrishna Gudipati 
45135fbe25c7SJing Huang /*
4514a36c61f9SKrishna Gudipati  *  fcs_scn_private FCS SCN private functions
4515a36c61f9SKrishna Gudipati  */
4516a36c61f9SKrishna Gudipati 
45175fbe25c7SJing Huang /*
4518a36c61f9SKrishna Gudipati  * This routine will be called to send a SCR command.
4519a36c61f9SKrishna Gudipati  */
4520a36c61f9SKrishna Gudipati static void
4521a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4522a36c61f9SKrishna Gudipati {
4523a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = scn_cbarg;
4524a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = scn->port;
4525a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4526a36c61f9SKrishna Gudipati 	int             len;
4527a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4528a36c61f9SKrishna Gudipati 
4529a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
4530a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4531a36c61f9SKrishna Gudipati 
4532a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
4533a36c61f9SKrishna Gudipati 	if (!fcxp) {
4534a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
4535a36c61f9SKrishna Gudipati 					bfa_fcs_lport_scn_send_scr, scn);
4536a36c61f9SKrishna Gudipati 		return;
4537a36c61f9SKrishna Gudipati 	}
4538a36c61f9SKrishna Gudipati 	scn->fcxp = fcxp;
4539a36c61f9SKrishna Gudipati 
4540a36c61f9SKrishna Gudipati 	/* Handle VU registrations for Base port only */
4541a36c61f9SKrishna Gudipati 	if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
4542a36c61f9SKrishna Gudipati 		len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4543f7f73812SMaggie Zhang 				port->fabric->lps->brcd_switch,
4544a36c61f9SKrishna Gudipati 				port->pid, 0);
4545a36c61f9SKrishna Gudipati 	} else {
4546a36c61f9SKrishna Gudipati 	    len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4547a36c61f9SKrishna Gudipati 				    BFA_FALSE,
4548a36c61f9SKrishna Gudipati 				    port->pid, 0);
4549a36c61f9SKrishna Gudipati 	}
4550a36c61f9SKrishna Gudipati 
4551a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4552a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4553a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_scn_scr_response,
4554a36c61f9SKrishna Gudipati 			  (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV);
4555a36c61f9SKrishna Gudipati 
4556a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT);
4557a36c61f9SKrishna Gudipati }
4558a36c61f9SKrishna Gudipati 
4559a36c61f9SKrishna Gudipati static void
4560a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4561a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
4562a36c61f9SKrishna Gudipati 			      u32 resid_len, struct fchs_s *rsp_fchs)
4563a36c61f9SKrishna Gudipati {
4564a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg;
4565a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = scn->port;
4566a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd;
4567a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
4568a36c61f9SKrishna Gudipati 
4569a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4570a36c61f9SKrishna Gudipati 
4571a36c61f9SKrishna Gudipati 	/*
4572a36c61f9SKrishna Gudipati 	 * Sanity Checks
4573a36c61f9SKrishna Gudipati 	 */
4574a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4575a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4576a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4577a36c61f9SKrishna Gudipati 		return;
4578a36c61f9SKrishna Gudipati 	}
4579a36c61f9SKrishna Gudipati 
4580a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
4581a36c61f9SKrishna Gudipati 
4582a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
4583a36c61f9SKrishna Gudipati 
4584a36c61f9SKrishna Gudipati 	case FC_ELS_ACC:
4585a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK);
4586a36c61f9SKrishna Gudipati 		break;
4587a36c61f9SKrishna Gudipati 
4588a36c61f9SKrishna Gudipati 	case FC_ELS_LS_RJT:
4589a36c61f9SKrishna Gudipati 
4590a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
4591a36c61f9SKrishna Gudipati 
4592a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code);
4593a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code_expl);
4594a36c61f9SKrishna Gudipati 
4595a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4596a36c61f9SKrishna Gudipati 		break;
4597a36c61f9SKrishna Gudipati 
4598a36c61f9SKrishna Gudipati 	default:
4599a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4600a36c61f9SKrishna Gudipati 	}
4601a36c61f9SKrishna Gudipati }
4602a36c61f9SKrishna Gudipati 
4603a36c61f9SKrishna Gudipati /*
4604a36c61f9SKrishna Gudipati  * Send a LS Accept
4605a36c61f9SKrishna Gudipati  */
4606a36c61f9SKrishna Gudipati static void
4607a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
4608a36c61f9SKrishna Gudipati 				struct fchs_s *rx_fchs)
4609a36c61f9SKrishna Gudipati {
4610a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4611a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4612a36c61f9SKrishna Gudipati 	struct bfa_rport_s *bfa_rport = NULL;
4613a36c61f9SKrishna Gudipati 	int             len;
4614a36c61f9SKrishna Gudipati 
4615a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
4616a36c61f9SKrishna Gudipati 
4617a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
4618a36c61f9SKrishna Gudipati 	if (!fcxp)
4619a36c61f9SKrishna Gudipati 		return;
4620a36c61f9SKrishna Gudipati 
4621a36c61f9SKrishna Gudipati 	len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4622a36c61f9SKrishna Gudipati 			      rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
4623a36c61f9SKrishna Gudipati 			      rx_fchs->ox_id);
4624a36c61f9SKrishna Gudipati 
4625a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
4626a36c61f9SKrishna Gudipati 			  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
4627a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, 0);
4628a36c61f9SKrishna Gudipati }
4629a36c61f9SKrishna Gudipati 
46305fbe25c7SJing Huang /*
4631a36c61f9SKrishna Gudipati  *     This routine will be called by bfa_timer on timer timeouts.
4632a36c61f9SKrishna Gudipati  *
4633a36c61f9SKrishna Gudipati  *	param[in]	vport		- pointer to bfa_fcs_lport_t.
4634a36c61f9SKrishna Gudipati  *	param[out]	vport_status	- pointer to return vport status in
4635a36c61f9SKrishna Gudipati  *
4636a36c61f9SKrishna Gudipati  *	return
4637a36c61f9SKrishna Gudipati  *		void
4638a36c61f9SKrishna Gudipati  *
4639a36c61f9SKrishna Gudipati  *	Special Considerations:
4640a36c61f9SKrishna Gudipati  *
4641a36c61f9SKrishna Gudipati  *	note
4642a36c61f9SKrishna Gudipati  */
4643a36c61f9SKrishna Gudipati static void
4644a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout(void *arg)
4645a36c61f9SKrishna Gudipati {
4646a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg;
4647a36c61f9SKrishna Gudipati 
4648a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT);
4649a36c61f9SKrishna Gudipati }
4650a36c61f9SKrishna Gudipati 
4651a36c61f9SKrishna Gudipati 
4652a36c61f9SKrishna Gudipati 
46535fbe25c7SJing Huang /*
4654a36c61f9SKrishna Gudipati  *  fcs_scn_public FCS state change notification public interfaces
4655a36c61f9SKrishna Gudipati  */
4656a36c61f9SKrishna Gudipati 
4657a36c61f9SKrishna Gudipati /*
4658a36c61f9SKrishna Gudipati  * Functions called by port/fab
4659a36c61f9SKrishna Gudipati  */
4660a36c61f9SKrishna Gudipati void
4661a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port)
4662a36c61f9SKrishna Gudipati {
4663a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4664a36c61f9SKrishna Gudipati 
4665a36c61f9SKrishna Gudipati 	scn->port = port;
4666a36c61f9SKrishna Gudipati 	bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4667a36c61f9SKrishna Gudipati }
4668a36c61f9SKrishna Gudipati 
4669a36c61f9SKrishna Gudipati void
4670a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port)
4671a36c61f9SKrishna Gudipati {
4672a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4673a36c61f9SKrishna Gudipati 
4674a36c61f9SKrishna Gudipati 	scn->port = port;
4675a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE);
4676a36c61f9SKrishna Gudipati }
4677a36c61f9SKrishna Gudipati 
4678a36c61f9SKrishna Gudipati void
4679a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port)
4680a36c61f9SKrishna Gudipati {
4681a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4682a36c61f9SKrishna Gudipati 
4683a36c61f9SKrishna Gudipati 	scn->port = port;
4684a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE);
4685a36c61f9SKrishna Gudipati }
4686a36c61f9SKrishna Gudipati 
4687a36c61f9SKrishna Gudipati static void
4688a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
4689a36c61f9SKrishna Gudipati {
4690a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
4691a36c61f9SKrishna Gudipati 
4692a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpid);
4693a36c61f9SKrishna Gudipati 
46945fbe25c7SJing Huang 	/*
4695a36c61f9SKrishna Gudipati 	 * If this is an unknown device, then it just came online.
4696a36c61f9SKrishna Gudipati 	 * Otherwise let rport handle the RSCN event.
4697a36c61f9SKrishna Gudipati 	 */
4698a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pid(port, rpid);
4699a36c61f9SKrishna Gudipati 	if (rport == NULL) {
4700a36c61f9SKrishna Gudipati 		/*
4701a36c61f9SKrishna Gudipati 		 * If min cfg mode is enabled, we donot need to
4702a36c61f9SKrishna Gudipati 		 * discover any new rports.
4703a36c61f9SKrishna Gudipati 		 */
4704a36c61f9SKrishna Gudipati 		if (!__fcs_min_cfg(port->fcs))
4705a36c61f9SKrishna Gudipati 			rport = bfa_fcs_rport_create(port, rpid);
4706a36c61f9SKrishna Gudipati 	} else
4707a36c61f9SKrishna Gudipati 		bfa_fcs_rport_scn(rport);
4708a36c61f9SKrishna Gudipati }
4709a36c61f9SKrishna Gudipati 
47105fbe25c7SJing Huang /*
4711a36c61f9SKrishna Gudipati  * rscn format based PID comparison
4712a36c61f9SKrishna Gudipati  */
4713a36c61f9SKrishna Gudipati #define __fc_pid_match(__c0, __c1, __fmt)		\
4714a36c61f9SKrishna Gudipati 	(((__fmt) == FC_RSCN_FORMAT_FABRIC) ||		\
4715a36c61f9SKrishna Gudipati 	 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) &&		\
4716a36c61f9SKrishna Gudipati 	  ((__c0)[0] == (__c1)[0])) ||				\
4717a36c61f9SKrishna Gudipati 	 (((__fmt) == FC_RSCN_FORMAT_AREA) &&		\
4718a36c61f9SKrishna Gudipati 	  ((__c0)[0] == (__c1)[0]) &&				\
4719a36c61f9SKrishna Gudipati 	  ((__c0)[1] == (__c1)[1])))
4720a36c61f9SKrishna Gudipati 
4721a36c61f9SKrishna Gudipati static void
4722a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port,
4723a36c61f9SKrishna Gudipati 				enum fc_rscn_format format,
4724a36c61f9SKrishna Gudipati 				u32 rscn_pid)
4725a36c61f9SKrishna Gudipati {
4726a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
4727a36c61f9SKrishna Gudipati 	struct list_head        *qe, *qe_next;
4728a36c61f9SKrishna Gudipati 	u8        *c0, *c1;
4729a36c61f9SKrishna Gudipati 
4730a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, format);
4731a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rscn_pid);
4732a36c61f9SKrishna Gudipati 
4733a36c61f9SKrishna Gudipati 	c0 = (u8 *) &rscn_pid;
4734a36c61f9SKrishna Gudipati 
4735a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qe_next, &port->rport_q) {
4736a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
4737a36c61f9SKrishna Gudipati 		c1 = (u8 *) &rport->pid;
4738a36c61f9SKrishna Gudipati 		if (__fc_pid_match(c0, c1, format))
4739a36c61f9SKrishna Gudipati 			bfa_fcs_rport_scn(rport);
4740a36c61f9SKrishna Gudipati 	}
4741a36c61f9SKrishna Gudipati }
4742a36c61f9SKrishna Gudipati 
4743a36c61f9SKrishna Gudipati 
4744a36c61f9SKrishna Gudipati void
4745a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
4746a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u32 len)
4747a36c61f9SKrishna Gudipati {
4748a36c61f9SKrishna Gudipati 	struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1);
4749a36c61f9SKrishna Gudipati 	int             num_entries;
4750a36c61f9SKrishna Gudipati 	u32        rscn_pid;
4751a36c61f9SKrishna Gudipati 	bfa_boolean_t   nsquery = BFA_FALSE, found;
4752a36c61f9SKrishna Gudipati 	int             i = 0, j;
4753a36c61f9SKrishna Gudipati 
4754a36c61f9SKrishna Gudipati 	num_entries =
4755ba816ea8SJing Huang 		(be16_to_cpu(rscn->payldlen) -
4756a36c61f9SKrishna Gudipati 		 sizeof(u32)) / sizeof(rscn->event[0]);
4757a36c61f9SKrishna Gudipati 
4758a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, num_entries);
4759a36c61f9SKrishna Gudipati 
4760a36c61f9SKrishna Gudipati 	port->stats.num_rscn++;
4761a36c61f9SKrishna Gudipati 
4762a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_send_ls_acc(port, fchs);
4763a36c61f9SKrishna Gudipati 
4764a36c61f9SKrishna Gudipati 	for (i = 0; i < num_entries; i++) {
4765a36c61f9SKrishna Gudipati 		rscn_pid = rscn->event[i].portid;
4766a36c61f9SKrishna Gudipati 
4767a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rscn->event[i].format);
4768a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rscn_pid);
4769a36c61f9SKrishna Gudipati 
4770a36c61f9SKrishna Gudipati 		/* check for duplicate entries in the list */
4771a36c61f9SKrishna Gudipati 		found = BFA_FALSE;
4772a36c61f9SKrishna Gudipati 		for (j = 0; j < i; j++) {
4773a36c61f9SKrishna Gudipati 			if (rscn->event[j].portid == rscn_pid) {
4774a36c61f9SKrishna Gudipati 				found = BFA_TRUE;
4775a36c61f9SKrishna Gudipati 				break;
4776a36c61f9SKrishna Gudipati 			}
4777a36c61f9SKrishna Gudipati 		}
4778a36c61f9SKrishna Gudipati 
4779a36c61f9SKrishna Gudipati 		/* if found in down the list, pid has been already processed */
4780a36c61f9SKrishna Gudipati 		if (found) {
4781a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rscn_pid);
4782a36c61f9SKrishna Gudipati 			continue;
4783a36c61f9SKrishna Gudipati 		}
4784a36c61f9SKrishna Gudipati 
4785a36c61f9SKrishna Gudipati 		switch (rscn->event[i].format) {
4786a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_PORTID:
4787a36c61f9SKrishna Gudipati 			if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) {
4788a36c61f9SKrishna Gudipati 				/*
4789a36c61f9SKrishna Gudipati 				 * Ignore this event.
4790a36c61f9SKrishna Gudipati 				 * f/w would have processed it
4791a36c61f9SKrishna Gudipati 				 */
4792a36c61f9SKrishna Gudipati 				bfa_trc(port->fcs, rscn_pid);
4793a36c61f9SKrishna Gudipati 			} else {
4794a36c61f9SKrishna Gudipati 				port->stats.num_portid_rscn++;
4795a36c61f9SKrishna Gudipati 				bfa_fcs_lport_scn_portid_rscn(port, rscn_pid);
4796a36c61f9SKrishna Gudipati 			}
4797a36c61f9SKrishna Gudipati 		break;
4798a36c61f9SKrishna Gudipati 
4799a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_FABRIC:
4800a36c61f9SKrishna Gudipati 			if (rscn->event[i].qualifier ==
4801a36c61f9SKrishna Gudipati 					FC_FABRIC_NAME_RSCN_EVENT) {
4802a36c61f9SKrishna Gudipati 				bfa_fcs_lport_ms_fabric_rscn(port);
4803a36c61f9SKrishna Gudipati 				break;
4804a36c61f9SKrishna Gudipati 			}
4805a36c61f9SKrishna Gudipati 			/* !!!!!!!!! Fall Through !!!!!!!!!!!!! */
4806a36c61f9SKrishna Gudipati 
4807a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_AREA:
4808a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_DOMAIN:
4809a36c61f9SKrishna Gudipati 			nsquery = BFA_TRUE;
4810a36c61f9SKrishna Gudipati 			bfa_fcs_lport_scn_multiport_rscn(port,
4811a36c61f9SKrishna Gudipati 							rscn->event[i].format,
4812a36c61f9SKrishna Gudipati 							rscn_pid);
4813a36c61f9SKrishna Gudipati 			break;
4814a36c61f9SKrishna Gudipati 
4815a36c61f9SKrishna Gudipati 
4816a36c61f9SKrishna Gudipati 		default:
4817d4b671c5SJing Huang 			WARN_ON(1);
4818a36c61f9SKrishna Gudipati 			nsquery = BFA_TRUE;
4819a36c61f9SKrishna Gudipati 		}
4820a36c61f9SKrishna Gudipati 	}
4821a36c61f9SKrishna Gudipati 
48225fbe25c7SJing Huang 	/*
48235fbe25c7SJing Huang 	 * If any of area, domain or fabric RSCN is received, do a fresh
48245fbe25c7SJing Huang 	 * discovery to find new devices.
4825a36c61f9SKrishna Gudipati 	 */
4826a36c61f9SKrishna Gudipati 	if (nsquery)
4827a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_query(port);
4828a36c61f9SKrishna Gudipati }
4829a36c61f9SKrishna Gudipati 
48305fbe25c7SJing Huang /*
4831a36c61f9SKrishna Gudipati  * BFA FCS port
4832a36c61f9SKrishna Gudipati  */
48335fbe25c7SJing Huang /*
4834a36c61f9SKrishna Gudipati  *  fcs_port_api BFA FCS port API
4835a36c61f9SKrishna Gudipati  */
4836a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *
4837a36c61f9SKrishna Gudipati bfa_fcs_get_base_port(struct bfa_fcs_s *fcs)
4838a36c61f9SKrishna Gudipati {
4839a36c61f9SKrishna Gudipati 	return &fcs->fabric.bport;
4840a36c61f9SKrishna Gudipati }
4841a36c61f9SKrishna Gudipati 
4842a36c61f9SKrishna Gudipati wwn_t
4843a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index,
4844a36c61f9SKrishna Gudipati 		int nrports, bfa_boolean_t bwwn)
4845a36c61f9SKrishna Gudipati {
4846a36c61f9SKrishna Gudipati 	struct list_head	*qh, *qe;
4847a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = NULL;
4848a36c61f9SKrishna Gudipati 	int	i;
4849a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs;
4850a36c61f9SKrishna Gudipati 
4851a36c61f9SKrishna Gudipati 	if (port == NULL || nrports == 0)
4852a36c61f9SKrishna Gudipati 		return (wwn_t) 0;
4853a36c61f9SKrishna Gudipati 
4854a36c61f9SKrishna Gudipati 	fcs = port->fcs;
4855a36c61f9SKrishna Gudipati 	bfa_trc(fcs, (u32) nrports);
4856a36c61f9SKrishna Gudipati 
4857a36c61f9SKrishna Gudipati 	i = 0;
4858a36c61f9SKrishna Gudipati 	qh = &port->rport_q;
4859a36c61f9SKrishna Gudipati 	qe = bfa_q_first(qh);
4860a36c61f9SKrishna Gudipati 
4861a36c61f9SKrishna Gudipati 	while ((qe != qh) && (i < nrports)) {
4862a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
4863f16a1750SMaggie Zhang 		if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
4864a36c61f9SKrishna Gudipati 			qe = bfa_q_next(qe);
4865a36c61f9SKrishna Gudipati 			bfa_trc(fcs, (u32) rport->pwwn);
4866a36c61f9SKrishna Gudipati 			bfa_trc(fcs, rport->pid);
4867a36c61f9SKrishna Gudipati 			bfa_trc(fcs, i);
4868a36c61f9SKrishna Gudipati 			continue;
4869a36c61f9SKrishna Gudipati 		}
4870a36c61f9SKrishna Gudipati 
4871a36c61f9SKrishna Gudipati 		if (bwwn) {
4872a36c61f9SKrishna Gudipati 			if (!memcmp(&wwn, &rport->pwwn, 8))
4873a36c61f9SKrishna Gudipati 				break;
4874a36c61f9SKrishna Gudipati 		} else {
4875a36c61f9SKrishna Gudipati 			if (i == index)
4876a36c61f9SKrishna Gudipati 				break;
4877a36c61f9SKrishna Gudipati 		}
4878a36c61f9SKrishna Gudipati 
4879a36c61f9SKrishna Gudipati 		i++;
4880a36c61f9SKrishna Gudipati 		qe = bfa_q_next(qe);
4881a36c61f9SKrishna Gudipati 	}
4882a36c61f9SKrishna Gudipati 
4883a36c61f9SKrishna Gudipati 	bfa_trc(fcs, i);
4884a36c61f9SKrishna Gudipati 	if (rport)
4885a36c61f9SKrishna Gudipati 		return rport->pwwn;
4886a36c61f9SKrishna Gudipati 	else
4887a36c61f9SKrishna Gudipati 		return (wwn_t) 0;
4888a36c61f9SKrishna Gudipati }
4889a36c61f9SKrishna Gudipati 
4890a36c61f9SKrishna Gudipati void
4891a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
4892a36c61f9SKrishna Gudipati 	 wwn_t rport_wwns[], int *nrports)
4893a36c61f9SKrishna Gudipati {
4894a36c61f9SKrishna Gudipati 	struct list_head	*qh, *qe;
4895a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = NULL;
4896a36c61f9SKrishna Gudipati 	int	i;
4897a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs;
4898a36c61f9SKrishna Gudipati 
4899a36c61f9SKrishna Gudipati 	if (port == NULL || rport_wwns == NULL || *nrports == 0)
4900a36c61f9SKrishna Gudipati 		return;
4901a36c61f9SKrishna Gudipati 
4902a36c61f9SKrishna Gudipati 	fcs = port->fcs;
4903a36c61f9SKrishna Gudipati 	bfa_trc(fcs, (u32) *nrports);
4904a36c61f9SKrishna Gudipati 
4905a36c61f9SKrishna Gudipati 	i = 0;
4906a36c61f9SKrishna Gudipati 	qh = &port->rport_q;
4907a36c61f9SKrishna Gudipati 	qe = bfa_q_first(qh);
4908a36c61f9SKrishna Gudipati 
4909a36c61f9SKrishna Gudipati 	while ((qe != qh) && (i < *nrports)) {
4910a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
4911f16a1750SMaggie Zhang 		if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
4912a36c61f9SKrishna Gudipati 			qe = bfa_q_next(qe);
4913a36c61f9SKrishna Gudipati 			bfa_trc(fcs, (u32) rport->pwwn);
4914a36c61f9SKrishna Gudipati 			bfa_trc(fcs, rport->pid);
4915a36c61f9SKrishna Gudipati 			bfa_trc(fcs, i);
4916a36c61f9SKrishna Gudipati 			continue;
4917a36c61f9SKrishna Gudipati 		}
4918a36c61f9SKrishna Gudipati 
4919a36c61f9SKrishna Gudipati 		rport_wwns[i] = rport->pwwn;
4920a36c61f9SKrishna Gudipati 
4921a36c61f9SKrishna Gudipati 		i++;
4922a36c61f9SKrishna Gudipati 		qe = bfa_q_next(qe);
4923a36c61f9SKrishna Gudipati 	}
4924a36c61f9SKrishna Gudipati 
4925a36c61f9SKrishna Gudipati 	bfa_trc(fcs, i);
4926a36c61f9SKrishna Gudipati 	*nrports = i;
4927a36c61f9SKrishna Gudipati }
4928a36c61f9SKrishna Gudipati 
4929a36c61f9SKrishna Gudipati /*
4930a36c61f9SKrishna Gudipati  * Iterate's through all the rport's in the given port to
4931a36c61f9SKrishna Gudipati  * determine the maximum operating speed.
4932a36c61f9SKrishna Gudipati  *
4933a36c61f9SKrishna Gudipati  * !!!! To be used in TRL Functionality only !!!!
4934a36c61f9SKrishna Gudipati  */
4935a36c61f9SKrishna Gudipati bfa_port_speed_t
4936a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port)
4937a36c61f9SKrishna Gudipati {
4938a36c61f9SKrishna Gudipati 	struct list_head *qh, *qe;
4939a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = NULL;
4940a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs;
4941a36c61f9SKrishna Gudipati 	bfa_port_speed_t max_speed = 0;
4942a36c61f9SKrishna Gudipati 	struct bfa_port_attr_s port_attr;
4943a36c61f9SKrishna Gudipati 	bfa_port_speed_t port_speed, rport_speed;
4944a36c61f9SKrishna Gudipati 	bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa);
4945a36c61f9SKrishna Gudipati 
4946a36c61f9SKrishna Gudipati 
4947a36c61f9SKrishna Gudipati 	if (port == NULL)
4948a36c61f9SKrishna Gudipati 		return 0;
4949a36c61f9SKrishna Gudipati 
4950a36c61f9SKrishna Gudipati 	fcs = port->fcs;
4951a36c61f9SKrishna Gudipati 
4952a36c61f9SKrishna Gudipati 	/* Get Physical port's current speed */
4953a36c61f9SKrishna Gudipati 	bfa_fcport_get_attr(port->fcs->bfa, &port_attr);
4954a36c61f9SKrishna Gudipati 	port_speed = port_attr.speed;
4955a36c61f9SKrishna Gudipati 	bfa_trc(fcs, port_speed);
4956a36c61f9SKrishna Gudipati 
4957a36c61f9SKrishna Gudipati 	qh = &port->rport_q;
4958a36c61f9SKrishna Gudipati 	qe = bfa_q_first(qh);
4959a36c61f9SKrishna Gudipati 
4960a36c61f9SKrishna Gudipati 	while (qe != qh) {
4961a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
4962f16a1750SMaggie Zhang 		if ((bfa_ntoh3b(rport->pid) > 0xFFF000) ||
4963d7be54ccSKrishna Gudipati 			(bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) ||
4964d7be54ccSKrishna Gudipati 			(rport->scsi_function != BFA_RPORT_TARGET)) {
4965a36c61f9SKrishna Gudipati 			qe = bfa_q_next(qe);
4966a36c61f9SKrishna Gudipati 			continue;
4967a36c61f9SKrishna Gudipati 		}
4968a36c61f9SKrishna Gudipati 
4969a36c61f9SKrishna Gudipati 		rport_speed = rport->rpf.rpsc_speed;
4970a36c61f9SKrishna Gudipati 		if ((trl_enabled) && (rport_speed ==
4971a36c61f9SKrishna Gudipati 			BFA_PORT_SPEED_UNKNOWN)) {
4972a36c61f9SKrishna Gudipati 			/* Use default ratelim speed setting */
4973a36c61f9SKrishna Gudipati 			rport_speed =
4974a36c61f9SKrishna Gudipati 				bfa_fcport_get_ratelim_speed(port->fcs->bfa);
4975a36c61f9SKrishna Gudipati 		}
4976a36c61f9SKrishna Gudipati 
4977d7be54ccSKrishna Gudipati 		if (rport_speed > max_speed)
4978a36c61f9SKrishna Gudipati 			max_speed = rport_speed;
4979a36c61f9SKrishna Gudipati 
4980a36c61f9SKrishna Gudipati 		qe = bfa_q_next(qe);
4981a36c61f9SKrishna Gudipati 	}
4982a36c61f9SKrishna Gudipati 
4983d7be54ccSKrishna Gudipati 	if (max_speed > port_speed)
4984d7be54ccSKrishna Gudipati 		max_speed = port_speed;
4985d7be54ccSKrishna Gudipati 
4986a36c61f9SKrishna Gudipati 	bfa_trc(fcs, max_speed);
4987a36c61f9SKrishna Gudipati 	return max_speed;
4988a36c61f9SKrishna Gudipati }
4989a36c61f9SKrishna Gudipati 
4990a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *
4991a36c61f9SKrishna Gudipati bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn)
4992a36c61f9SKrishna Gudipati {
4993a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
4994a36c61f9SKrishna Gudipati 	bfa_fcs_vf_t   *vf;
4995a36c61f9SKrishna Gudipati 
4996d4b671c5SJing Huang 	WARN_ON(fcs == NULL);
4997a36c61f9SKrishna Gudipati 
4998a36c61f9SKrishna Gudipati 	vf = bfa_fcs_vf_lookup(fcs, vf_id);
4999a36c61f9SKrishna Gudipati 	if (vf == NULL) {
5000a36c61f9SKrishna Gudipati 		bfa_trc(fcs, vf_id);
5001a36c61f9SKrishna Gudipati 		return NULL;
5002a36c61f9SKrishna Gudipati 	}
5003a36c61f9SKrishna Gudipati 
5004a36c61f9SKrishna Gudipati 	if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
5005a36c61f9SKrishna Gudipati 		return &vf->bport;
5006a36c61f9SKrishna Gudipati 
5007a36c61f9SKrishna Gudipati 	vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
5008a36c61f9SKrishna Gudipati 	if (vport)
5009a36c61f9SKrishna Gudipati 		return &vport->lport;
5010a36c61f9SKrishna Gudipati 
5011a36c61f9SKrishna Gudipati 	return NULL;
5012a36c61f9SKrishna Gudipati }
5013a36c61f9SKrishna Gudipati 
5014a36c61f9SKrishna Gudipati /*
5015a36c61f9SKrishna Gudipati  *  API corresponding to NPIV_VPORT_GETINFO.
5016a36c61f9SKrishna Gudipati  */
5017a36c61f9SKrishna Gudipati void
5018a36c61f9SKrishna Gudipati bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
5019a36c61f9SKrishna Gudipati 	 struct bfa_lport_info_s *port_info)
5020a36c61f9SKrishna Gudipati {
5021a36c61f9SKrishna Gudipati 
5022a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->fabric->fabric_name);
5023a36c61f9SKrishna Gudipati 
5024a36c61f9SKrishna Gudipati 	if (port->vport == NULL) {
5025a36c61f9SKrishna Gudipati 		/*
5026a36c61f9SKrishna Gudipati 		 * This is a Physical port
5027a36c61f9SKrishna Gudipati 		 */
5028a36c61f9SKrishna Gudipati 		port_info->port_type = BFA_LPORT_TYPE_PHYSICAL;
5029a36c61f9SKrishna Gudipati 
5030a36c61f9SKrishna Gudipati 		/*
5031a36c61f9SKrishna Gudipati 		 * @todo : need to fix the state & reason
5032a36c61f9SKrishna Gudipati 		 */
5033a36c61f9SKrishna Gudipati 		port_info->port_state = 0;
5034a36c61f9SKrishna Gudipati 		port_info->offline_reason = 0;
5035a36c61f9SKrishna Gudipati 
5036a36c61f9SKrishna Gudipati 		port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5037a36c61f9SKrishna Gudipati 		port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5038a36c61f9SKrishna Gudipati 
5039a36c61f9SKrishna Gudipati 		port_info->max_vports_supp =
5040a36c61f9SKrishna Gudipati 			bfa_lps_get_max_vport(port->fcs->bfa);
5041a36c61f9SKrishna Gudipati 		port_info->num_vports_inuse =
5042f7f73812SMaggie Zhang 			port->fabric->num_vports;
5043a36c61f9SKrishna Gudipati 		port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
5044a36c61f9SKrishna Gudipati 		port_info->num_rports_inuse = port->num_rports;
5045a36c61f9SKrishna Gudipati 	} else {
5046a36c61f9SKrishna Gudipati 		/*
5047a36c61f9SKrishna Gudipati 		 * This is a virtual port
5048a36c61f9SKrishna Gudipati 		 */
5049a36c61f9SKrishna Gudipati 		port_info->port_type = BFA_LPORT_TYPE_VIRTUAL;
5050a36c61f9SKrishna Gudipati 
5051a36c61f9SKrishna Gudipati 		/*
5052a36c61f9SKrishna Gudipati 		 * @todo : need to fix the state & reason
5053a36c61f9SKrishna Gudipati 		 */
5054a36c61f9SKrishna Gudipati 		port_info->port_state = 0;
5055a36c61f9SKrishna Gudipati 		port_info->offline_reason = 0;
5056a36c61f9SKrishna Gudipati 
5057a36c61f9SKrishna Gudipati 		port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5058a36c61f9SKrishna Gudipati 		port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5059a36c61f9SKrishna Gudipati 	}
5060a36c61f9SKrishna Gudipati }
5061a36c61f9SKrishna Gudipati 
5062a36c61f9SKrishna Gudipati void
5063a36c61f9SKrishna Gudipati bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port,
5064a36c61f9SKrishna Gudipati 	 struct bfa_lport_stats_s *port_stats)
5065a36c61f9SKrishna Gudipati {
5066a36c61f9SKrishna Gudipati 	*port_stats = fcs_port->stats;
5067a36c61f9SKrishna Gudipati }
5068a36c61f9SKrishna Gudipati 
5069a36c61f9SKrishna Gudipati void
5070a36c61f9SKrishna Gudipati bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port)
5071a36c61f9SKrishna Gudipati {
50726a18b167SJing Huang 	memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s));
5073a36c61f9SKrishna Gudipati }
5074a36c61f9SKrishna Gudipati 
50755fbe25c7SJing Huang /*
5076a36c61f9SKrishna Gudipati  * FCS virtual port state machine
5077a36c61f9SKrishna Gudipati  */
5078a36c61f9SKrishna Gudipati 
5079a36c61f9SKrishna Gudipati #define __vport_fcs(__vp)       ((__vp)->lport.fcs)
5080a36c61f9SKrishna Gudipati #define __vport_pwwn(__vp)      ((__vp)->lport.port_cfg.pwwn)
5081a36c61f9SKrishna Gudipati #define __vport_nwwn(__vp)      ((__vp)->lport.port_cfg.nwwn)
5082a36c61f9SKrishna Gudipati #define __vport_bfa(__vp)       ((__vp)->lport.fcs->bfa)
5083a36c61f9SKrishna Gudipati #define __vport_fcid(__vp)      ((__vp)->lport.pid)
5084a36c61f9SKrishna Gudipati #define __vport_fabric(__vp)    ((__vp)->lport.fabric)
5085a36c61f9SKrishna Gudipati #define __vport_vfid(__vp)      ((__vp)->lport.fabric->vf_id)
5086a36c61f9SKrishna Gudipati 
5087a36c61f9SKrishna Gudipati #define BFA_FCS_VPORT_MAX_RETRIES  5
5088a36c61f9SKrishna Gudipati /*
5089a36c61f9SKrishna Gudipati  * Forward declarations
5090a36c61f9SKrishna Gudipati  */
5091a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport);
5092a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_timeout(void *vport_arg);
5093a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport);
5094a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport);
5095a36c61f9SKrishna Gudipati 
50965fbe25c7SJing Huang /*
5097a36c61f9SKrishna Gudipati  *  fcs_vport_sm FCS virtual port state machine
5098a36c61f9SKrishna Gudipati  */
5099a36c61f9SKrishna Gudipati 
51005fbe25c7SJing Huang /*
5101a36c61f9SKrishna Gudipati  * VPort State Machine events
5102a36c61f9SKrishna Gudipati  */
5103a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event {
5104a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_CREATE = 1,	/*  vport create event */
5105a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_DELETE = 2,	/*  vport delete event */
5106a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_START = 3,	/*  vport start request */
5107a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_STOP = 4,	/*  stop: unsupported */
5108a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_ONLINE = 5,	/*  fabric online */
5109a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_OFFLINE = 6,	/*  fabric offline event */
5110a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_FRMSENT = 7,	/*  fdisc/logo sent events */
5111a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_OK = 8,	/*  good response */
5112a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_ERROR = 9,	/*  error/bad response */
5113a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_TIMEOUT = 10,	/*  delay timer event */
5114a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_DELCOMP = 11,	/*  lport delete completion */
5115a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12,	/*  Dup wnn error*/
5116a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_FAILED = 13,	/*  non-retryable failure */
5117dd5aaf45SKrishna Gudipati 	BFA_FCS_VPORT_SM_STOPCOMP = 14,	/* vport delete completion */
5118a36c61f9SKrishna Gudipati };
5119a36c61f9SKrishna Gudipati 
5120a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
5121a36c61f9SKrishna Gudipati 					enum bfa_fcs_vport_event event);
5122a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
5123a36c61f9SKrishna Gudipati 					 enum bfa_fcs_vport_event event);
5124a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
5125a36c61f9SKrishna Gudipati 					 enum bfa_fcs_vport_event event);
5126a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
5127a36c61f9SKrishna Gudipati 				       enum bfa_fcs_vport_event event);
5128a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
5129a36c61f9SKrishna Gudipati 					     enum bfa_fcs_vport_event event);
5130d7be54ccSKrishna Gudipati static void	bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
5131d7be54ccSKrishna Gudipati 					enum bfa_fcs_vport_event event);
5132a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
5133a36c61f9SKrishna Gudipati 					enum bfa_fcs_vport_event event);
5134a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
5135a36c61f9SKrishna Gudipati 					  enum bfa_fcs_vport_event event);
5136a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
5137a36c61f9SKrishna Gudipati 					 enum bfa_fcs_vport_event event);
5138a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
5139a36c61f9SKrishna Gudipati 				      enum bfa_fcs_vport_event event);
5140a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
5141a36c61f9SKrishna Gudipati 				      enum bfa_fcs_vport_event event);
5142dd5aaf45SKrishna Gudipati static void	bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
5143dd5aaf45SKrishna Gudipati 					enum bfa_fcs_vport_event event);
5144dd5aaf45SKrishna Gudipati static void	bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
5145dd5aaf45SKrishna Gudipati 					enum bfa_fcs_vport_event event);
5146a36c61f9SKrishna Gudipati 
5147a36c61f9SKrishna Gudipati static struct bfa_sm_table_s  vport_sm_table[] = {
5148a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT},
5149a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED},
5150a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE},
5151a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC},
5152a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY},
5153d7be54ccSKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT},
5154a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE},
5155a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING},
5156a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP},
5157a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO},
5158a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR}
5159a36c61f9SKrishna Gudipati };
5160a36c61f9SKrishna Gudipati 
51615fbe25c7SJing Huang /*
5162a36c61f9SKrishna Gudipati  * Beginning state.
5163a36c61f9SKrishna Gudipati  */
5164a36c61f9SKrishna Gudipati static void
5165a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
5166a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5167a36c61f9SKrishna Gudipati {
5168a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5169a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5170a36c61f9SKrishna Gudipati 
5171a36c61f9SKrishna Gudipati 	switch (event) {
5172a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_CREATE:
5173a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5174a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_addvport(__vport_fabric(vport), vport);
5175a36c61f9SKrishna Gudipati 		break;
5176a36c61f9SKrishna Gudipati 
5177a36c61f9SKrishna Gudipati 	default:
5178a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5179a36c61f9SKrishna Gudipati 	}
5180a36c61f9SKrishna Gudipati }
5181a36c61f9SKrishna Gudipati 
51825fbe25c7SJing Huang /*
5183a36c61f9SKrishna Gudipati  * Created state - a start event is required to start up the state machine.
5184a36c61f9SKrishna Gudipati  */
5185a36c61f9SKrishna Gudipati static void
5186a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
5187a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5188a36c61f9SKrishna Gudipati {
5189a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5190a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5191a36c61f9SKrishna Gudipati 
5192a36c61f9SKrishna Gudipati 	switch (event) {
5193a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_START:
5194f7f73812SMaggie Zhang 		if (bfa_sm_cmp_state(__vport_fabric(vport),
5195f7f73812SMaggie Zhang 					bfa_fcs_fabric_sm_online)
5196a36c61f9SKrishna Gudipati 		    && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) {
5197a36c61f9SKrishna Gudipati 			bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5198a36c61f9SKrishna Gudipati 			bfa_fcs_vport_do_fdisc(vport);
5199a36c61f9SKrishna Gudipati 		} else {
52005fbe25c7SJing Huang 			/*
5201a36c61f9SKrishna Gudipati 			 * Fabric is offline or not NPIV capable, stay in
5202a36c61f9SKrishna Gudipati 			 * offline state.
5203a36c61f9SKrishna Gudipati 			 */
5204a36c61f9SKrishna Gudipati 			vport->vport_stats.fab_no_npiv++;
5205a36c61f9SKrishna Gudipati 			bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5206a36c61f9SKrishna Gudipati 		}
5207a36c61f9SKrishna Gudipati 		break;
5208a36c61f9SKrishna Gudipati 
5209a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5210a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5211a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5212a36c61f9SKrishna Gudipati 		break;
5213a36c61f9SKrishna Gudipati 
5214a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_ONLINE:
5215a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
52165fbe25c7SJing Huang 		/*
5217a36c61f9SKrishna Gudipati 		 * Ignore ONLINE/OFFLINE events from fabric
5218a36c61f9SKrishna Gudipati 		 * till vport is started.
5219a36c61f9SKrishna Gudipati 		 */
5220a36c61f9SKrishna Gudipati 		break;
5221a36c61f9SKrishna Gudipati 
5222a36c61f9SKrishna Gudipati 	default:
5223a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5224a36c61f9SKrishna Gudipati 	}
5225a36c61f9SKrishna Gudipati }
5226a36c61f9SKrishna Gudipati 
52275fbe25c7SJing Huang /*
5228a36c61f9SKrishna Gudipati  * Offline state - awaiting ONLINE event from fabric SM.
5229a36c61f9SKrishna Gudipati  */
5230a36c61f9SKrishna Gudipati static void
5231a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
5232a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5233a36c61f9SKrishna Gudipati {
5234a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5235a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5236a36c61f9SKrishna Gudipati 
5237a36c61f9SKrishna Gudipati 	switch (event) {
5238a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5239a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5240a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5241a36c61f9SKrishna Gudipati 		break;
5242a36c61f9SKrishna Gudipati 
5243a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_ONLINE:
5244a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5245a36c61f9SKrishna Gudipati 		vport->fdisc_retries = 0;
5246a36c61f9SKrishna Gudipati 		bfa_fcs_vport_do_fdisc(vport);
5247a36c61f9SKrishna Gudipati 		break;
5248a36c61f9SKrishna Gudipati 
5249dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOP:
5250dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5251dd5aaf45SKrishna Gudipati 		bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
5252dd5aaf45SKrishna Gudipati 		break;
5253dd5aaf45SKrishna Gudipati 
5254a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5255a36c61f9SKrishna Gudipati 		/*
5256a36c61f9SKrishna Gudipati 		 * This can happen if the vport couldn't be initialzied
5257a36c61f9SKrishna Gudipati 		 * due the fact that the npiv was not enabled on the switch.
5258a36c61f9SKrishna Gudipati 		 * In that case we will put the vport in offline state.
5259a36c61f9SKrishna Gudipati 		 * However, the link can go down and cause the this event to
5260a36c61f9SKrishna Gudipati 		 * be sent when we are already offline. Ignore it.
5261a36c61f9SKrishna Gudipati 		 */
5262a36c61f9SKrishna Gudipati 		break;
5263a36c61f9SKrishna Gudipati 
5264a36c61f9SKrishna Gudipati 	default:
5265a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5266a36c61f9SKrishna Gudipati 	}
5267a36c61f9SKrishna Gudipati }
5268a36c61f9SKrishna Gudipati 
5269a36c61f9SKrishna Gudipati 
52705fbe25c7SJing Huang /*
5271a36c61f9SKrishna Gudipati  * FDISC is sent and awaiting reply from fabric.
5272a36c61f9SKrishna Gudipati  */
5273a36c61f9SKrishna Gudipati static void
5274a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
5275a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5276a36c61f9SKrishna Gudipati {
5277a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5278a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5279a36c61f9SKrishna Gudipati 
5280a36c61f9SKrishna Gudipati 	switch (event) {
5281a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5282d7be54ccSKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait);
5283a36c61f9SKrishna Gudipati 		break;
5284a36c61f9SKrishna Gudipati 
5285a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5286a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5287f7f73812SMaggie Zhang 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5288a36c61f9SKrishna Gudipati 		break;
5289a36c61f9SKrishna Gudipati 
5290a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
5291a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_online);
5292a36c61f9SKrishna Gudipati 		bfa_fcs_lport_online(&vport->lport);
5293a36c61f9SKrishna Gudipati 		break;
5294a36c61f9SKrishna Gudipati 
5295a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
5296a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry);
5297a36c61f9SKrishna Gudipati 		bfa_timer_start(__vport_bfa(vport), &vport->timer,
5298a36c61f9SKrishna Gudipati 				    bfa_fcs_vport_timeout, vport,
5299a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
5300a36c61f9SKrishna Gudipati 		break;
5301a36c61f9SKrishna Gudipati 
5302a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_FAILED:
5303a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5304a36c61f9SKrishna Gudipati 		break;
5305a36c61f9SKrishna Gudipati 
5306a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
5307a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_error);
5308a36c61f9SKrishna Gudipati 		break;
5309a36c61f9SKrishna Gudipati 
5310a36c61f9SKrishna Gudipati 	default:
5311a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5312a36c61f9SKrishna Gudipati 	}
5313a36c61f9SKrishna Gudipati }
5314a36c61f9SKrishna Gudipati 
53155fbe25c7SJing Huang /*
5316a36c61f9SKrishna Gudipati  * FDISC attempt failed - a timer is active to retry FDISC.
5317a36c61f9SKrishna Gudipati  */
5318a36c61f9SKrishna Gudipati static void
5319a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
5320a36c61f9SKrishna Gudipati 			     enum bfa_fcs_vport_event event)
5321a36c61f9SKrishna Gudipati {
5322a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5323a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5324a36c61f9SKrishna Gudipati 
5325a36c61f9SKrishna Gudipati 	switch (event) {
5326a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5327a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5328a36c61f9SKrishna Gudipati 		bfa_timer_stop(&vport->timer);
5329a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5330a36c61f9SKrishna Gudipati 		break;
5331a36c61f9SKrishna Gudipati 
5332a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5333a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5334a36c61f9SKrishna Gudipati 		bfa_timer_stop(&vport->timer);
5335a36c61f9SKrishna Gudipati 		break;
5336a36c61f9SKrishna Gudipati 
5337a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_TIMEOUT:
5338a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5339a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_retries++;
5340a36c61f9SKrishna Gudipati 		vport->fdisc_retries++;
5341a36c61f9SKrishna Gudipati 		bfa_fcs_vport_do_fdisc(vport);
5342a36c61f9SKrishna Gudipati 		break;
5343a36c61f9SKrishna Gudipati 
5344a36c61f9SKrishna Gudipati 	default:
5345a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5346a36c61f9SKrishna Gudipati 	}
5347a36c61f9SKrishna Gudipati }
5348a36c61f9SKrishna Gudipati 
53495fbe25c7SJing Huang /*
5350d7be54ccSKrishna Gudipati  * FDISC is in progress and we got a vport delete request -
5351d7be54ccSKrishna Gudipati  * this is a wait state while we wait for fdisc response and
5352d7be54ccSKrishna Gudipati  * we will transition to the appropriate state - on rsp status.
5353d7be54ccSKrishna Gudipati  */
5354d7be54ccSKrishna Gudipati static void
5355d7be54ccSKrishna Gudipati bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
5356d7be54ccSKrishna Gudipati 				enum bfa_fcs_vport_event event)
5357d7be54ccSKrishna Gudipati {
5358d7be54ccSKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5359d7be54ccSKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5360d7be54ccSKrishna Gudipati 
5361d7be54ccSKrishna Gudipati 	switch (event) {
5362d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
5363d7be54ccSKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
5364d7be54ccSKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5365d7be54ccSKrishna Gudipati 		break;
5366d7be54ccSKrishna Gudipati 
5367d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5368d7be54ccSKrishna Gudipati 		break;
5369d7be54ccSKrishna Gudipati 
5370d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5371d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
5372d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_FAILED:
5373d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
5374d7be54ccSKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5375d7be54ccSKrishna Gudipati 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5376d7be54ccSKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5377d7be54ccSKrishna Gudipati 		break;
5378d7be54ccSKrishna Gudipati 
5379d7be54ccSKrishna Gudipati 	default:
5380d7be54ccSKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5381d7be54ccSKrishna Gudipati 	}
5382d7be54ccSKrishna Gudipati }
5383d7be54ccSKrishna Gudipati 
5384d7be54ccSKrishna Gudipati /*
5385a36c61f9SKrishna Gudipati  * Vport is online (FDISC is complete).
5386a36c61f9SKrishna Gudipati  */
5387a36c61f9SKrishna Gudipati static void
5388a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
5389a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5390a36c61f9SKrishna Gudipati {
5391a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5392a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5393a36c61f9SKrishna Gudipati 
5394a36c61f9SKrishna Gudipati 	switch (event) {
5395a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5396a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
5397a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5398a36c61f9SKrishna Gudipati 		break;
5399a36c61f9SKrishna Gudipati 
5400dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOP:
5401dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping);
5402dd5aaf45SKrishna Gudipati 		bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
5403dd5aaf45SKrishna Gudipati 		break;
5404dd5aaf45SKrishna Gudipati 
5405a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5406a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5407f7f73812SMaggie Zhang 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5408a36c61f9SKrishna Gudipati 		bfa_fcs_lport_offline(&vport->lport);
5409a36c61f9SKrishna Gudipati 		break;
5410a36c61f9SKrishna Gudipati 
5411a36c61f9SKrishna Gudipati 	default:
5412a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5413a36c61f9SKrishna Gudipati 	}
5414a36c61f9SKrishna Gudipati }
5415a36c61f9SKrishna Gudipati 
54165fbe25c7SJing Huang /*
5417dd5aaf45SKrishna Gudipati  * Vport is being stopped - awaiting lport stop completion to send
5418dd5aaf45SKrishna Gudipati  * LOGO to fabric.
5419dd5aaf45SKrishna Gudipati  */
5420dd5aaf45SKrishna Gudipati static void
5421dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
5422dd5aaf45SKrishna Gudipati 			  enum bfa_fcs_vport_event event)
5423dd5aaf45SKrishna Gudipati {
5424dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5425dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5426dd5aaf45SKrishna Gudipati 
5427dd5aaf45SKrishna Gudipati 	switch (event) {
5428dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOPCOMP:
5429dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop);
5430dd5aaf45SKrishna Gudipati 		bfa_fcs_vport_do_logo(vport);
5431dd5aaf45SKrishna Gudipati 		break;
5432dd5aaf45SKrishna Gudipati 
5433dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5434dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5435dd5aaf45SKrishna Gudipati 		break;
5436dd5aaf45SKrishna Gudipati 
5437dd5aaf45SKrishna Gudipati 	default:
5438dd5aaf45SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5439dd5aaf45SKrishna Gudipati 	}
5440dd5aaf45SKrishna Gudipati }
5441dd5aaf45SKrishna Gudipati 
5442dd5aaf45SKrishna Gudipati /*
5443a36c61f9SKrishna Gudipati  * Vport is being deleted - awaiting lport delete completion to send
5444a36c61f9SKrishna Gudipati  * LOGO to fabric.
5445a36c61f9SKrishna Gudipati  */
5446a36c61f9SKrishna Gudipati static void
5447a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
5448a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5449a36c61f9SKrishna Gudipati {
5450a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5451a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5452a36c61f9SKrishna Gudipati 
5453a36c61f9SKrishna Gudipati 	switch (event) {
5454a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5455a36c61f9SKrishna Gudipati 		break;
5456a36c61f9SKrishna Gudipati 
5457a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELCOMP:
5458a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
5459a36c61f9SKrishna Gudipati 		bfa_fcs_vport_do_logo(vport);
5460a36c61f9SKrishna Gudipati 		break;
5461a36c61f9SKrishna Gudipati 
5462a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5463a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5464a36c61f9SKrishna Gudipati 		break;
5465a36c61f9SKrishna Gudipati 
5466a36c61f9SKrishna Gudipati 	default:
5467a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5468a36c61f9SKrishna Gudipati 	}
5469a36c61f9SKrishna Gudipati }
5470a36c61f9SKrishna Gudipati 
54715fbe25c7SJing Huang /*
5472a36c61f9SKrishna Gudipati  * Error State.
5473a36c61f9SKrishna Gudipati  * This state will be set when the Vport Creation fails due
5474a36c61f9SKrishna Gudipati  * to errors like Dup WWN. In this state only operation allowed
5475a36c61f9SKrishna Gudipati  * is a Vport Delete.
5476a36c61f9SKrishna Gudipati  */
5477a36c61f9SKrishna Gudipati static void
5478a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
5479a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5480a36c61f9SKrishna Gudipati {
5481a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5482a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5483a36c61f9SKrishna Gudipati 
5484a36c61f9SKrishna Gudipati 	switch (event) {
5485a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5486a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5487a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5488a36c61f9SKrishna Gudipati 		break;
5489a36c61f9SKrishna Gudipati 
5490a36c61f9SKrishna Gudipati 	default:
5491a36c61f9SKrishna Gudipati 		bfa_trc(__vport_fcs(vport), event);
5492a36c61f9SKrishna Gudipati 	}
5493a36c61f9SKrishna Gudipati }
5494a36c61f9SKrishna Gudipati 
54955fbe25c7SJing Huang /*
5496a36c61f9SKrishna Gudipati  * Lport cleanup is in progress since vport is being deleted. Fabric is
5497a36c61f9SKrishna Gudipati  * offline, so no LOGO is needed to complete vport deletion.
5498a36c61f9SKrishna Gudipati  */
5499a36c61f9SKrishna Gudipati static void
5500a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
5501a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5502a36c61f9SKrishna Gudipati {
5503a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5504a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5505a36c61f9SKrishna Gudipati 
5506a36c61f9SKrishna Gudipati 	switch (event) {
5507a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELCOMP:
5508a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5509a36c61f9SKrishna Gudipati 		bfa_fcs_vport_free(vport);
5510a36c61f9SKrishna Gudipati 		break;
5511a36c61f9SKrishna Gudipati 
5512dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOPCOMP:
5513dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5514dd5aaf45SKrishna Gudipati 		break;
5515dd5aaf45SKrishna Gudipati 
5516a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5517a36c61f9SKrishna Gudipati 		break;
5518a36c61f9SKrishna Gudipati 
5519a36c61f9SKrishna Gudipati 	default:
5520a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5521a36c61f9SKrishna Gudipati 	}
5522a36c61f9SKrishna Gudipati }
5523a36c61f9SKrishna Gudipati 
55245fbe25c7SJing Huang /*
5525dd5aaf45SKrishna Gudipati  * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup
5526dd5aaf45SKrishna Gudipati  * is done.
5527dd5aaf45SKrishna Gudipati  */
5528dd5aaf45SKrishna Gudipati static void
5529dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
5530dd5aaf45SKrishna Gudipati 			       enum bfa_fcs_vport_event event)
5531dd5aaf45SKrishna Gudipati {
5532dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5533dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5534dd5aaf45SKrishna Gudipati 
5535dd5aaf45SKrishna Gudipati 	switch (event) {
5536dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5537dd5aaf45SKrishna Gudipati 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5538dd5aaf45SKrishna Gudipati 		/*
5539dd5aaf45SKrishna Gudipati 		 * !!! fall through !!!
5540dd5aaf45SKrishna Gudipati 		 */
5541dd5aaf45SKrishna Gudipati 
5542dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
5543dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
5544dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5545dd5aaf45SKrishna Gudipati 		break;
5546dd5aaf45SKrishna Gudipati 
5547dd5aaf45SKrishna Gudipati 	default:
5548dd5aaf45SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5549dd5aaf45SKrishna Gudipati 	}
5550dd5aaf45SKrishna Gudipati }
5551dd5aaf45SKrishna Gudipati 
5552dd5aaf45SKrishna Gudipati /*
5553a36c61f9SKrishna Gudipati  * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
5554a36c61f9SKrishna Gudipati  * is done.
5555a36c61f9SKrishna Gudipati  */
5556a36c61f9SKrishna Gudipati static void
5557a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
5558a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5559a36c61f9SKrishna Gudipati {
5560a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5561a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5562a36c61f9SKrishna Gudipati 
5563a36c61f9SKrishna Gudipati 	switch (event) {
5564a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5565f7f73812SMaggie Zhang 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5566a36c61f9SKrishna Gudipati 		/*
5567a36c61f9SKrishna Gudipati 		 * !!! fall through !!!
5568a36c61f9SKrishna Gudipati 		 */
5569a36c61f9SKrishna Gudipati 
5570a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
5571a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
5572a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5573a36c61f9SKrishna Gudipati 		bfa_fcs_vport_free(vport);
5574a36c61f9SKrishna Gudipati 		break;
5575a36c61f9SKrishna Gudipati 
5576a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5577a36c61f9SKrishna Gudipati 		break;
5578a36c61f9SKrishna Gudipati 
5579a36c61f9SKrishna Gudipati 	default:
5580a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5581a36c61f9SKrishna Gudipati 	}
5582a36c61f9SKrishna Gudipati }
5583a36c61f9SKrishna Gudipati 
5584a36c61f9SKrishna Gudipati 
5585a36c61f9SKrishna Gudipati 
55865fbe25c7SJing Huang /*
5587a36c61f9SKrishna Gudipati  *  fcs_vport_private FCS virtual port private functions
5588a36c61f9SKrishna Gudipati  */
55895fbe25c7SJing Huang /*
55907826f304SKrishna Gudipati  * Send AEN notification
55917826f304SKrishna Gudipati  */
55927826f304SKrishna Gudipati static void
55937826f304SKrishna Gudipati bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port,
55947826f304SKrishna Gudipati 		       enum bfa_lport_aen_event event)
55957826f304SKrishna Gudipati {
55967826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
55977826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
55987826f304SKrishna Gudipati 
55997826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
56007826f304SKrishna Gudipati 	if (!aen_entry)
56017826f304SKrishna Gudipati 		return;
56027826f304SKrishna Gudipati 
56037826f304SKrishna Gudipati 	aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
56047826f304SKrishna Gudipati 	aen_entry->aen_data.lport.roles = port->port_cfg.roles;
56057826f304SKrishna Gudipati 	aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
56067826f304SKrishna Gudipati 					bfa_fcs_get_base_port(port->fcs));
56077826f304SKrishna Gudipati 	aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
56087826f304SKrishna Gudipati 
56097826f304SKrishna Gudipati 	/* Send the AEN notification */
56107826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
56117826f304SKrishna Gudipati 				  BFA_AEN_CAT_LPORT, event);
56127826f304SKrishna Gudipati }
56137826f304SKrishna Gudipati 
56147826f304SKrishna Gudipati /*
5615a36c61f9SKrishna Gudipati  * This routine will be called to send a FDISC command.
5616a36c61f9SKrishna Gudipati  */
5617a36c61f9SKrishna Gudipati static void
5618a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
5619a36c61f9SKrishna Gudipati {
5620a36c61f9SKrishna Gudipati 	bfa_lps_fdisc(vport->lps, vport,
5621a36c61f9SKrishna Gudipati 		bfa_fcport_get_maxfrsize(__vport_bfa(vport)),
5622a36c61f9SKrishna Gudipati 		__vport_pwwn(vport), __vport_nwwn(vport));
5623a36c61f9SKrishna Gudipati 	vport->vport_stats.fdisc_sent++;
5624a36c61f9SKrishna Gudipati }
5625a36c61f9SKrishna Gudipati 
5626a36c61f9SKrishna Gudipati static void
5627a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
5628a36c61f9SKrishna Gudipati {
5629f7f73812SMaggie Zhang 	u8		lsrjt_rsn = vport->lps->lsrjt_rsn;
5630f7f73812SMaggie Zhang 	u8		lsrjt_expl = vport->lps->lsrjt_expl;
5631a36c61f9SKrishna Gudipati 
5632a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), lsrjt_rsn);
5633a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), lsrjt_expl);
5634a36c61f9SKrishna Gudipati 
5635a36c61f9SKrishna Gudipati 	/* For certain reason codes, we don't want to retry. */
5636f7f73812SMaggie Zhang 	switch (vport->lps->lsrjt_expl) {
5637a36c61f9SKrishna Gudipati 	case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */
5638a36c61f9SKrishna Gudipati 	case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
5639a36c61f9SKrishna Gudipati 		if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
5640a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
56417826f304SKrishna Gudipati 		else {
56427826f304SKrishna Gudipati 			bfa_fcs_vport_aen_post(&vport->lport,
56437826f304SKrishna Gudipati 					BFA_LPORT_AEN_NPIV_DUP_WWN);
5644a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN);
56457826f304SKrishna Gudipati 		}
5646a36c61f9SKrishna Gudipati 		break;
5647a36c61f9SKrishna Gudipati 
5648a36c61f9SKrishna Gudipati 	case FC_LS_RJT_EXP_INSUFF_RES:
5649a36c61f9SKrishna Gudipati 		/*
5650a36c61f9SKrishna Gudipati 		 * This means max logins per port/switch setting on the
5651a36c61f9SKrishna Gudipati 		 * switch was exceeded.
5652a36c61f9SKrishna Gudipati 		 */
5653a36c61f9SKrishna Gudipati 		if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
5654a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
56557826f304SKrishna Gudipati 		else {
56567826f304SKrishna Gudipati 			bfa_fcs_vport_aen_post(&vport->lport,
56577826f304SKrishna Gudipati 					BFA_LPORT_AEN_NPIV_FABRIC_MAX);
5658a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
56597826f304SKrishna Gudipati 		}
5660a36c61f9SKrishna Gudipati 		break;
5661a36c61f9SKrishna Gudipati 
5662a36c61f9SKrishna Gudipati 	default:
56637826f304SKrishna Gudipati 		if (vport->fdisc_retries == 0)
56647826f304SKrishna Gudipati 			bfa_fcs_vport_aen_post(&vport->lport,
56657826f304SKrishna Gudipati 					BFA_LPORT_AEN_NPIV_UNKNOWN);
5666a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5667a36c61f9SKrishna Gudipati 	}
5668a36c61f9SKrishna Gudipati }
5669a36c61f9SKrishna Gudipati 
56705fbe25c7SJing Huang /*
5671a36c61f9SKrishna Gudipati  *	Called to send a logout to the fabric. Used when a V-Port is
5672a36c61f9SKrishna Gudipati  *	deleted/stopped.
5673a36c61f9SKrishna Gudipati  */
5674a36c61f9SKrishna Gudipati static void
5675a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport)
5676a36c61f9SKrishna Gudipati {
5677a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5678a36c61f9SKrishna Gudipati 
5679a36c61f9SKrishna Gudipati 	vport->vport_stats.logo_sent++;
5680a36c61f9SKrishna Gudipati 	bfa_lps_fdisclogo(vport->lps);
5681a36c61f9SKrishna Gudipati }
5682a36c61f9SKrishna Gudipati 
5683a36c61f9SKrishna Gudipati 
56845fbe25c7SJing Huang /*
5685a36c61f9SKrishna Gudipati  *     This routine will be called by bfa_timer on timer timeouts.
5686a36c61f9SKrishna Gudipati  *
5687a36c61f9SKrishna Gudipati  *	param[in]	vport		- pointer to bfa_fcs_vport_t.
5688a36c61f9SKrishna Gudipati  *	param[out]	vport_status	- pointer to return vport status in
5689a36c61f9SKrishna Gudipati  *
5690a36c61f9SKrishna Gudipati  *	return
5691a36c61f9SKrishna Gudipati  *		void
5692a36c61f9SKrishna Gudipati  *
5693a36c61f9SKrishna Gudipati  *	Special Considerations:
5694a36c61f9SKrishna Gudipati  *
5695a36c61f9SKrishna Gudipati  *	note
5696a36c61f9SKrishna Gudipati  */
5697a36c61f9SKrishna Gudipati static void
5698a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout(void *vport_arg)
5699a36c61f9SKrishna Gudipati {
5700a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg;
5701a36c61f9SKrishna Gudipati 
5702a36c61f9SKrishna Gudipati 	vport->vport_stats.fdisc_timeouts++;
5703a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT);
5704a36c61f9SKrishna Gudipati }
5705a36c61f9SKrishna Gudipati 
5706a36c61f9SKrishna Gudipati static void
5707a36c61f9SKrishna Gudipati bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
5708a36c61f9SKrishna Gudipati {
5709a36c61f9SKrishna Gudipati 	struct bfad_vport_s *vport_drv =
5710a36c61f9SKrishna Gudipati 			(struct bfad_vport_s *)vport->vport_drv;
5711a36c61f9SKrishna Gudipati 
5712a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
5713a36c61f9SKrishna Gudipati 	bfa_lps_delete(vport->lps);
571417c201b3SKrishna Gudipati 
571517c201b3SKrishna Gudipati 	if (vport_drv->comp_del) {
571617c201b3SKrishna Gudipati 		complete(vport_drv->comp_del);
571717c201b3SKrishna Gudipati 		return;
5718a36c61f9SKrishna Gudipati 	}
5719a36c61f9SKrishna Gudipati 
572017c201b3SKrishna Gudipati 	/*
572117c201b3SKrishna Gudipati 	 * We queue the vport delete work to the IM work_q from here.
572217c201b3SKrishna Gudipati 	 * The memory for the bfad_vport_s is freed from the FC function
572317c201b3SKrishna Gudipati 	 * template vport_delete entry point.
572417c201b3SKrishna Gudipati 	 */
572517c201b3SKrishna Gudipati 	if (vport_drv)
572617c201b3SKrishna Gudipati 		bfad_im_port_delete(vport_drv->drv_port.bfad,
572717c201b3SKrishna Gudipati 				&vport_drv->drv_port);
572817c201b3SKrishna Gudipati }
5729a36c61f9SKrishna Gudipati 
57305fbe25c7SJing Huang /*
5731a36c61f9SKrishna Gudipati  *  fcs_vport_public FCS virtual port public interfaces
5732a36c61f9SKrishna Gudipati  */
5733a36c61f9SKrishna Gudipati 
57345fbe25c7SJing Huang /*
5735a36c61f9SKrishna Gudipati  * Online notification from fabric SM.
5736a36c61f9SKrishna Gudipati  */
5737a36c61f9SKrishna Gudipati void
5738a36c61f9SKrishna Gudipati bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport)
5739a36c61f9SKrishna Gudipati {
5740a36c61f9SKrishna Gudipati 	vport->vport_stats.fab_online++;
5741d7be54ccSKrishna Gudipati 	if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport)))
5742a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
5743d7be54ccSKrishna Gudipati 	else
5744d7be54ccSKrishna Gudipati 		vport->vport_stats.fab_no_npiv++;
5745a36c61f9SKrishna Gudipati }
5746a36c61f9SKrishna Gudipati 
57475fbe25c7SJing Huang /*
5748a36c61f9SKrishna Gudipati  * Offline notification from fabric SM.
5749a36c61f9SKrishna Gudipati  */
5750a36c61f9SKrishna Gudipati void
5751a36c61f9SKrishna Gudipati bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport)
5752a36c61f9SKrishna Gudipati {
5753a36c61f9SKrishna Gudipati 	vport->vport_stats.fab_offline++;
5754a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
5755a36c61f9SKrishna Gudipati }
5756a36c61f9SKrishna Gudipati 
57575fbe25c7SJing Huang /*
5758a36c61f9SKrishna Gudipati  * Cleanup notification from fabric SM on link timer expiry.
5759a36c61f9SKrishna Gudipati  */
5760a36c61f9SKrishna Gudipati void
5761a36c61f9SKrishna Gudipati bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
5762a36c61f9SKrishna Gudipati {
5763a36c61f9SKrishna Gudipati 	vport->vport_stats.fab_cleanup++;
5764a36c61f9SKrishna Gudipati }
57655fbe25c7SJing Huang /*
5766a36c61f9SKrishna Gudipati  * delete notification from fabric SM. To be invoked from within FCS.
5767a36c61f9SKrishna Gudipati  */
5768a36c61f9SKrishna Gudipati void
5769a36c61f9SKrishna Gudipati bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport)
5770a36c61f9SKrishna Gudipati {
5771a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
5772a36c61f9SKrishna Gudipati }
5773a36c61f9SKrishna Gudipati 
57745fbe25c7SJing Huang /*
5775dd5aaf45SKrishna Gudipati  * Stop completion callback from associated lport
5776dd5aaf45SKrishna Gudipati  */
5777dd5aaf45SKrishna Gudipati void
5778dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport)
5779dd5aaf45SKrishna Gudipati {
5780dd5aaf45SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP);
5781dd5aaf45SKrishna Gudipati }
5782dd5aaf45SKrishna Gudipati 
5783dd5aaf45SKrishna Gudipati /*
5784a36c61f9SKrishna Gudipati  * Delete completion callback from associated lport
5785a36c61f9SKrishna Gudipati  */
5786a36c61f9SKrishna Gudipati void
5787a36c61f9SKrishna Gudipati bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
5788a36c61f9SKrishna Gudipati {
5789a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP);
5790a36c61f9SKrishna Gudipati }
5791a36c61f9SKrishna Gudipati 
5792a36c61f9SKrishna Gudipati 
5793a36c61f9SKrishna Gudipati 
57945fbe25c7SJing Huang /*
5795a36c61f9SKrishna Gudipati  *  fcs_vport_api Virtual port API
5796a36c61f9SKrishna Gudipati  */
5797a36c61f9SKrishna Gudipati 
57985fbe25c7SJing Huang /*
5799a36c61f9SKrishna Gudipati  *	Use this function to instantiate a new FCS vport object. This
5800a36c61f9SKrishna Gudipati  *	function will not trigger any HW initialization process (which will be
5801a36c61f9SKrishna Gudipati  *	done in vport_start() call)
5802a36c61f9SKrishna Gudipati  *
5803a36c61f9SKrishna Gudipati  *	param[in] vport	-		pointer to bfa_fcs_vport_t. This space
5804a36c61f9SKrishna Gudipati  *					needs to be allocated by the driver.
5805a36c61f9SKrishna Gudipati  *	param[in] fcs		-	FCS instance
5806a36c61f9SKrishna Gudipati  *	param[in] vport_cfg	-	vport configuration
5807a36c61f9SKrishna Gudipati  *	param[in] vf_id		-	VF_ID if vport is created within a VF.
5808a36c61f9SKrishna Gudipati  *					FC_VF_ID_NULL to specify base fabric.
5809a36c61f9SKrishna Gudipati  *	param[in] vport_drv	-	Opaque handle back to the driver's vport
5810a36c61f9SKrishna Gudipati  *					structure
5811a36c61f9SKrishna Gudipati  *
5812a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_OK - on success.
5813a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_FAILED - on failure.
5814a36c61f9SKrishna Gudipati  */
5815a36c61f9SKrishna Gudipati bfa_status_t
5816a36c61f9SKrishna Gudipati bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
5817a36c61f9SKrishna Gudipati 		u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
5818a36c61f9SKrishna Gudipati 		struct bfad_vport_s *vport_drv)
5819a36c61f9SKrishna Gudipati {
5820a36c61f9SKrishna Gudipati 	if (vport_cfg->pwwn == 0)
5821a36c61f9SKrishna Gudipati 		return BFA_STATUS_INVALID_WWN;
5822a36c61f9SKrishna Gudipati 
5823a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
5824a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_WWN_BP;
5825a36c61f9SKrishna Gudipati 
5826a36c61f9SKrishna Gudipati 	if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
5827a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_EXISTS;
5828a36c61f9SKrishna Gudipati 
5829f7f73812SMaggie Zhang 	if (fcs->fabric.num_vports ==
5830a36c61f9SKrishna Gudipati 			bfa_lps_get_max_vport(fcs->bfa))
5831a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_MAX;
5832a36c61f9SKrishna Gudipati 
5833a36c61f9SKrishna Gudipati 	vport->lps = bfa_lps_alloc(fcs->bfa);
5834a36c61f9SKrishna Gudipati 	if (!vport->lps)
5835a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_MAX;
5836a36c61f9SKrishna Gudipati 
5837a36c61f9SKrishna Gudipati 	vport->vport_drv = vport_drv;
5838a36c61f9SKrishna Gudipati 	vport_cfg->preboot_vp = BFA_FALSE;
5839a36c61f9SKrishna Gudipati 
5840a36c61f9SKrishna Gudipati 	bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5841a36c61f9SKrishna Gudipati 	bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
5842a36c61f9SKrishna Gudipati 	bfa_fcs_lport_init(&vport->lport, vport_cfg);
5843a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
5844a36c61f9SKrishna Gudipati 
5845a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
5846a36c61f9SKrishna Gudipati }
5847a36c61f9SKrishna Gudipati 
58485fbe25c7SJing Huang /*
5849a36c61f9SKrishna Gudipati  *	Use this function to instantiate a new FCS PBC vport object. This
5850a36c61f9SKrishna Gudipati  *	function will not trigger any HW initialization process (which will be
5851a36c61f9SKrishna Gudipati  *	done in vport_start() call)
5852a36c61f9SKrishna Gudipati  *
5853a36c61f9SKrishna Gudipati  *	param[in] vport	-	pointer to bfa_fcs_vport_t. This space
5854a36c61f9SKrishna Gudipati  *				needs to be allocated by the driver.
5855a36c61f9SKrishna Gudipati  *	param[in] fcs	-	FCS instance
5856a36c61f9SKrishna Gudipati  *	param[in] vport_cfg	-	vport configuration
5857a36c61f9SKrishna Gudipati  *	param[in] vf_id		-	VF_ID if vport is created within a VF.
5858a36c61f9SKrishna Gudipati  *					FC_VF_ID_NULL to specify base fabric.
5859a36c61f9SKrishna Gudipati  *	param[in] vport_drv	-	Opaque handle back to the driver's vport
5860a36c61f9SKrishna Gudipati  *					structure
5861a36c61f9SKrishna Gudipati  *
5862a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_OK - on success.
5863a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_FAILED - on failure.
5864a36c61f9SKrishna Gudipati  */
5865a36c61f9SKrishna Gudipati bfa_status_t
5866a36c61f9SKrishna Gudipati bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
5867a36c61f9SKrishna Gudipati 			u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
5868a36c61f9SKrishna Gudipati 			struct bfad_vport_s *vport_drv)
5869a36c61f9SKrishna Gudipati {
5870a36c61f9SKrishna Gudipati 	bfa_status_t rc;
5871a36c61f9SKrishna Gudipati 
5872a36c61f9SKrishna Gudipati 	rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv);
5873a36c61f9SKrishna Gudipati 	vport->lport.port_cfg.preboot_vp = BFA_TRUE;
5874a36c61f9SKrishna Gudipati 
5875a36c61f9SKrishna Gudipati 	return rc;
5876a36c61f9SKrishna Gudipati }
5877a36c61f9SKrishna Gudipati 
58785fbe25c7SJing Huang /*
5879a36c61f9SKrishna Gudipati  *	Use this function to findout if this is a pbc vport or not.
5880a36c61f9SKrishna Gudipati  *
5881a36c61f9SKrishna Gudipati  * @param[in] vport - pointer to bfa_fcs_vport_t.
5882a36c61f9SKrishna Gudipati  *
5883a36c61f9SKrishna Gudipati  * @returns None
5884a36c61f9SKrishna Gudipati  */
5885a36c61f9SKrishna Gudipati bfa_boolean_t
5886a36c61f9SKrishna Gudipati bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport)
5887a36c61f9SKrishna Gudipati {
5888a36c61f9SKrishna Gudipati 
5889a36c61f9SKrishna Gudipati 	if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE))
5890a36c61f9SKrishna Gudipati 		return BFA_TRUE;
5891a36c61f9SKrishna Gudipati 	else
5892a36c61f9SKrishna Gudipati 		return BFA_FALSE;
5893a36c61f9SKrishna Gudipati 
5894a36c61f9SKrishna Gudipati }
5895a36c61f9SKrishna Gudipati 
58965fbe25c7SJing Huang /*
5897a36c61f9SKrishna Gudipati  * Use this function initialize the vport.
5898a36c61f9SKrishna Gudipati  *
5899a36c61f9SKrishna Gudipati  * @param[in] vport - pointer to bfa_fcs_vport_t.
5900a36c61f9SKrishna Gudipati  *
5901a36c61f9SKrishna Gudipati  * @returns None
5902a36c61f9SKrishna Gudipati  */
5903a36c61f9SKrishna Gudipati bfa_status_t
5904a36c61f9SKrishna Gudipati bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport)
5905a36c61f9SKrishna Gudipati {
5906a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START);
5907a36c61f9SKrishna Gudipati 
5908a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
5909a36c61f9SKrishna Gudipati }
5910a36c61f9SKrishna Gudipati 
59115fbe25c7SJing Huang /*
5912a36c61f9SKrishna Gudipati  *	Use this function quiese the vport object. This function will return
5913a36c61f9SKrishna Gudipati  *	immediately, when the vport is actually stopped, the
5914a36c61f9SKrishna Gudipati  *	bfa_drv_vport_stop_cb() will be called.
5915a36c61f9SKrishna Gudipati  *
5916a36c61f9SKrishna Gudipati  *	param[in] vport - pointer to bfa_fcs_vport_t.
5917a36c61f9SKrishna Gudipati  *
5918a36c61f9SKrishna Gudipati  *	return None
5919a36c61f9SKrishna Gudipati  */
5920a36c61f9SKrishna Gudipati bfa_status_t
5921a36c61f9SKrishna Gudipati bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
5922a36c61f9SKrishna Gudipati {
5923a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
5924a36c61f9SKrishna Gudipati 
5925a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
5926a36c61f9SKrishna Gudipati }
5927a36c61f9SKrishna Gudipati 
59285fbe25c7SJing Huang /*
5929a36c61f9SKrishna Gudipati  *	Use this function to delete a vport object. Fabric object should
5930a36c61f9SKrishna Gudipati  *	be stopped before this function call.
5931a36c61f9SKrishna Gudipati  *
5932a36c61f9SKrishna Gudipati  *	!!!!!!! Donot invoke this from within FCS  !!!!!!!
5933a36c61f9SKrishna Gudipati  *
5934a36c61f9SKrishna Gudipati  *	param[in] vport - pointer to bfa_fcs_vport_t.
5935a36c61f9SKrishna Gudipati  *
5936a36c61f9SKrishna Gudipati  *	return     None
5937a36c61f9SKrishna Gudipati  */
5938a36c61f9SKrishna Gudipati bfa_status_t
5939a36c61f9SKrishna Gudipati bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport)
5940a36c61f9SKrishna Gudipati {
5941a36c61f9SKrishna Gudipati 
5942a36c61f9SKrishna Gudipati 	if (vport->lport.port_cfg.preboot_vp)
5943a36c61f9SKrishna Gudipati 		return BFA_STATUS_PBC;
5944a36c61f9SKrishna Gudipati 
5945a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
5946a36c61f9SKrishna Gudipati 
5947a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
5948a36c61f9SKrishna Gudipati }
5949a36c61f9SKrishna Gudipati 
59505fbe25c7SJing Huang /*
5951a36c61f9SKrishna Gudipati  *	Use this function to get vport's current status info.
5952a36c61f9SKrishna Gudipati  *
5953a36c61f9SKrishna Gudipati  *	param[in] vport		pointer to bfa_fcs_vport_t.
5954a36c61f9SKrishna Gudipati  *	param[out] attr		pointer to return vport attributes
5955a36c61f9SKrishna Gudipati  *
5956a36c61f9SKrishna Gudipati  *	return None
5957a36c61f9SKrishna Gudipati  */
5958a36c61f9SKrishna Gudipati void
5959a36c61f9SKrishna Gudipati bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
5960a36c61f9SKrishna Gudipati 			struct bfa_vport_attr_s *attr)
5961a36c61f9SKrishna Gudipati {
5962a36c61f9SKrishna Gudipati 	if (vport == NULL || attr == NULL)
5963a36c61f9SKrishna Gudipati 		return;
5964a36c61f9SKrishna Gudipati 
59656a18b167SJing Huang 	memset(attr, 0, sizeof(struct bfa_vport_attr_s));
5966a36c61f9SKrishna Gudipati 
5967a36c61f9SKrishna Gudipati 	bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr);
5968a36c61f9SKrishna Gudipati 	attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
5969a36c61f9SKrishna Gudipati }
5970a36c61f9SKrishna Gudipati 
5971a36c61f9SKrishna Gudipati 
59725fbe25c7SJing Huang /*
5973a36c61f9SKrishna Gudipati  *	Lookup a virtual port. Excludes base port from lookup.
5974a36c61f9SKrishna Gudipati  */
5975a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *
5976a36c61f9SKrishna Gudipati bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn)
5977a36c61f9SKrishna Gudipati {
5978a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
5979a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
5980a36c61f9SKrishna Gudipati 
5981a36c61f9SKrishna Gudipati 	bfa_trc(fcs, vf_id);
5982a36c61f9SKrishna Gudipati 	bfa_trc(fcs, vpwwn);
5983a36c61f9SKrishna Gudipati 
5984a36c61f9SKrishna Gudipati 	fabric = bfa_fcs_vf_lookup(fcs, vf_id);
5985a36c61f9SKrishna Gudipati 	if (!fabric) {
5986a36c61f9SKrishna Gudipati 		bfa_trc(fcs, vf_id);
5987a36c61f9SKrishna Gudipati 		return NULL;
5988a36c61f9SKrishna Gudipati 	}
5989a36c61f9SKrishna Gudipati 
5990a36c61f9SKrishna Gudipati 	vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn);
5991a36c61f9SKrishna Gudipati 	return vport;
5992a36c61f9SKrishna Gudipati }
5993a36c61f9SKrishna Gudipati 
59945fbe25c7SJing Huang /*
5995a36c61f9SKrishna Gudipati  * FDISC Response
5996a36c61f9SKrishna Gudipati  */
5997a36c61f9SKrishna Gudipati void
5998a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
5999a36c61f9SKrishna Gudipati {
6000a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = uarg;
6001a36c61f9SKrishna Gudipati 
6002a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6003a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), status);
6004a36c61f9SKrishna Gudipati 
6005a36c61f9SKrishna Gudipati 	switch (status) {
6006a36c61f9SKrishna Gudipati 	case BFA_STATUS_OK:
6007a36c61f9SKrishna Gudipati 		/*
6008b595076aSUwe Kleine-König 		 * Initialize the V-Port fields
6009a36c61f9SKrishna Gudipati 		 */
6010f7f73812SMaggie Zhang 		__vport_fcid(vport) = vport->lps->lp_pid;
6011a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_accepts++;
6012a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
6013a36c61f9SKrishna Gudipati 		break;
6014a36c61f9SKrishna Gudipati 
6015a36c61f9SKrishna Gudipati 	case BFA_STATUS_INVALID_MAC:
6016a36c61f9SKrishna Gudipati 		/* Only for CNA */
6017a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_acc_bad++;
6018a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6019a36c61f9SKrishna Gudipati 
6020a36c61f9SKrishna Gudipati 		break;
6021a36c61f9SKrishna Gudipati 
6022a36c61f9SKrishna Gudipati 	case BFA_STATUS_EPROTOCOL:
6023f7f73812SMaggie Zhang 		switch (vport->lps->ext_status) {
6024a36c61f9SKrishna Gudipati 		case BFA_EPROTO_BAD_ACCEPT:
6025a36c61f9SKrishna Gudipati 			vport->vport_stats.fdisc_acc_bad++;
6026a36c61f9SKrishna Gudipati 			break;
6027a36c61f9SKrishna Gudipati 
6028a36c61f9SKrishna Gudipati 		case BFA_EPROTO_UNKNOWN_RSP:
6029a36c61f9SKrishna Gudipati 			vport->vport_stats.fdisc_unknown_rsp++;
6030a36c61f9SKrishna Gudipati 			break;
6031a36c61f9SKrishna Gudipati 
6032a36c61f9SKrishna Gudipati 		default:
6033a36c61f9SKrishna Gudipati 			break;
6034a36c61f9SKrishna Gudipati 		}
6035a36c61f9SKrishna Gudipati 
6036a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6037a36c61f9SKrishna Gudipati 		break;
6038a36c61f9SKrishna Gudipati 
6039a36c61f9SKrishna Gudipati 	case BFA_STATUS_FABRIC_RJT:
6040a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_rejects++;
6041a36c61f9SKrishna Gudipati 		bfa_fcs_vport_fdisc_rejected(vport);
6042a36c61f9SKrishna Gudipati 		break;
6043a36c61f9SKrishna Gudipati 
6044a36c61f9SKrishna Gudipati 	default:
6045a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_rsp_err++;
6046a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6047a36c61f9SKrishna Gudipati 	}
6048a36c61f9SKrishna Gudipati }
6049a36c61f9SKrishna Gudipati 
60505fbe25c7SJing Huang /*
6051a36c61f9SKrishna Gudipati  * LOGO response
6052a36c61f9SKrishna Gudipati  */
6053a36c61f9SKrishna Gudipati void
6054a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
6055a36c61f9SKrishna Gudipati {
6056a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = uarg;
6057a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
6058a36c61f9SKrishna Gudipati }
6059a36c61f9SKrishna Gudipati 
60605fbe25c7SJing Huang /*
6061a36c61f9SKrishna Gudipati  * Received clear virtual link
6062a36c61f9SKrishna Gudipati  */
6063a36c61f9SKrishna Gudipati void
6064a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(void *bfad, void *uarg)
6065a36c61f9SKrishna Gudipati {
6066a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = uarg;
6067a36c61f9SKrishna Gudipati 
6068a36c61f9SKrishna Gudipati 	/* Send an Offline followed by an ONLINE */
6069a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
6070a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
6071a36c61f9SKrishna Gudipati }
6072