xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs_lport.c (revision 881c1b3c)
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);
134881c1b3cSKrishna Gudipati 		else
135881c1b3cSKrishna Gudipati 			bfa_wc_down(&(port->fabric->stop_wc));
136dd5aaf45SKrishna Gudipati 		break;
137dd5aaf45SKrishna Gudipati 
1383e98cc01SJing Huang 	case BFA_FCS_PORT_SM_OFFLINE:
1393e98cc01SJing Huang 		break;
1403e98cc01SJing Huang 
1417725ccfdSJing Huang 	default:
142e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1437725ccfdSJing Huang 	}
1447725ccfdSJing Huang }
1457725ccfdSJing Huang 
1467725ccfdSJing Huang static void
147a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_online(
148a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
149a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
1507725ccfdSJing Huang {
1517725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
1527725ccfdSJing Huang 	struct list_head		*qe, *qen;
1537725ccfdSJing Huang 
1547725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1557725ccfdSJing Huang 	bfa_trc(port->fcs, event);
1567725ccfdSJing Huang 
1577725ccfdSJing Huang 	switch (event) {
1587725ccfdSJing Huang 	case BFA_FCS_PORT_SM_OFFLINE:
159a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_offline);
160a36c61f9SKrishna Gudipati 		bfa_fcs_lport_offline_actions(port);
1617725ccfdSJing Huang 		break;
1627725ccfdSJing Huang 
163dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_STOP:
164dd5aaf45SKrishna Gudipati 		__port_action[port->fabric->fab_type].offline(port);
165dd5aaf45SKrishna Gudipati 
166dd5aaf45SKrishna Gudipati 		if (port->num_rports == 0) {
167dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
168dd5aaf45SKrishna Gudipati 			/* If vport - send completion call back */
169dd5aaf45SKrishna Gudipati 			if (port->vport)
170dd5aaf45SKrishna Gudipati 				bfa_fcs_vport_stop_comp(port->vport);
171881c1b3cSKrishna Gudipati 			else
172881c1b3cSKrishna Gudipati 				bfa_wc_down(&(port->fabric->stop_wc));
173dd5aaf45SKrishna Gudipati 		} else {
174dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
175dd5aaf45SKrishna Gudipati 			list_for_each_safe(qe, qen, &port->rport_q) {
176dd5aaf45SKrishna Gudipati 				rport = (struct bfa_fcs_rport_s *) qe;
177dd5aaf45SKrishna Gudipati 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
178dd5aaf45SKrishna Gudipati 			}
179dd5aaf45SKrishna Gudipati 		}
180dd5aaf45SKrishna Gudipati 		break;
181dd5aaf45SKrishna Gudipati 
1827725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELETE:
1837725ccfdSJing Huang 
1847725ccfdSJing Huang 		__port_action[port->fabric->fab_type].offline(port);
1857725ccfdSJing Huang 
1867725ccfdSJing Huang 		if (port->num_rports == 0) {
187a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
188a36c61f9SKrishna Gudipati 			bfa_fcs_lport_deleted(port);
1897725ccfdSJing Huang 		} else {
190a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
1917725ccfdSJing Huang 			list_for_each_safe(qe, qen, &port->rport_q) {
1927725ccfdSJing Huang 				rport = (struct bfa_fcs_rport_s *) qe;
193f7f73812SMaggie Zhang 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1947725ccfdSJing Huang 			}
1957725ccfdSJing Huang 		}
1967725ccfdSJing Huang 		break;
1977725ccfdSJing Huang 
1987725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELRPORT:
1997725ccfdSJing Huang 		break;
2007725ccfdSJing Huang 
2017725ccfdSJing Huang 	default:
202e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
2037725ccfdSJing Huang 	}
2047725ccfdSJing Huang }
2057725ccfdSJing Huang 
2067725ccfdSJing Huang static void
207a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_offline(
208a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
209a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
2107725ccfdSJing Huang {
2117725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
2127725ccfdSJing Huang 	struct list_head		*qe, *qen;
2137725ccfdSJing Huang 
2147725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2157725ccfdSJing Huang 	bfa_trc(port->fcs, event);
2167725ccfdSJing Huang 
2177725ccfdSJing Huang 	switch (event) {
2187725ccfdSJing Huang 	case BFA_FCS_PORT_SM_ONLINE:
219a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
220a36c61f9SKrishna Gudipati 		bfa_fcs_lport_online_actions(port);
2217725ccfdSJing Huang 		break;
2227725ccfdSJing Huang 
223dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_STOP:
224dd5aaf45SKrishna Gudipati 		if (port->num_rports == 0) {
225dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
226dd5aaf45SKrishna Gudipati 			/* If vport - send completion call back */
227dd5aaf45SKrishna Gudipati 			if (port->vport)
228dd5aaf45SKrishna Gudipati 				bfa_fcs_vport_stop_comp(port->vport);
229881c1b3cSKrishna Gudipati 			else
230881c1b3cSKrishna Gudipati 				bfa_wc_down(&(port->fabric->stop_wc));
231dd5aaf45SKrishna Gudipati 		} else {
232dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
233dd5aaf45SKrishna Gudipati 			list_for_each_safe(qe, qen, &port->rport_q) {
234dd5aaf45SKrishna Gudipati 				rport = (struct bfa_fcs_rport_s *) qe;
235dd5aaf45SKrishna Gudipati 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
236dd5aaf45SKrishna Gudipati 			}
237dd5aaf45SKrishna Gudipati 		}
238dd5aaf45SKrishna Gudipati 		break;
239dd5aaf45SKrishna Gudipati 
2407725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELETE:
2417725ccfdSJing Huang 		if (port->num_rports == 0) {
242a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
243a36c61f9SKrishna Gudipati 			bfa_fcs_lport_deleted(port);
2447725ccfdSJing Huang 		} else {
245a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
2467725ccfdSJing Huang 			list_for_each_safe(qe, qen, &port->rport_q) {
2477725ccfdSJing Huang 				rport = (struct bfa_fcs_rport_s *) qe;
248f7f73812SMaggie Zhang 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
2497725ccfdSJing Huang 			}
2507725ccfdSJing Huang 		}
2517725ccfdSJing Huang 		break;
2527725ccfdSJing Huang 
2537725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELRPORT:
2547725ccfdSJing Huang 	case BFA_FCS_PORT_SM_OFFLINE:
2557725ccfdSJing Huang 		break;
2567725ccfdSJing Huang 
2577725ccfdSJing Huang 	default:
258e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
2597725ccfdSJing Huang 	}
2607725ccfdSJing Huang }
2617725ccfdSJing Huang 
2627725ccfdSJing Huang static void
263dd5aaf45SKrishna Gudipati bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
264dd5aaf45SKrishna Gudipati 			  enum bfa_fcs_lport_event event)
265dd5aaf45SKrishna Gudipati {
266dd5aaf45SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
267dd5aaf45SKrishna Gudipati 	bfa_trc(port->fcs, event);
268dd5aaf45SKrishna Gudipati 
269dd5aaf45SKrishna Gudipati 	switch (event) {
270dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_DELRPORT:
271dd5aaf45SKrishna Gudipati 		if (port->num_rports == 0) {
272dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
273dd5aaf45SKrishna Gudipati 			/* If vport - send completion call back */
274dd5aaf45SKrishna Gudipati 			if (port->vport)
275dd5aaf45SKrishna Gudipati 				bfa_fcs_vport_stop_comp(port->vport);
276881c1b3cSKrishna Gudipati 			else
277881c1b3cSKrishna Gudipati 				bfa_wc_down(&(port->fabric->stop_wc));
278dd5aaf45SKrishna Gudipati 		}
279dd5aaf45SKrishna Gudipati 		break;
280dd5aaf45SKrishna Gudipati 
281dd5aaf45SKrishna Gudipati 	default:
282dd5aaf45SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
283dd5aaf45SKrishna Gudipati 	}
284dd5aaf45SKrishna Gudipati }
285dd5aaf45SKrishna Gudipati 
286dd5aaf45SKrishna Gudipati static void
287a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_deleting(
288a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
289a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
2907725ccfdSJing Huang {
2917725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2927725ccfdSJing Huang 	bfa_trc(port->fcs, event);
2937725ccfdSJing Huang 
2947725ccfdSJing Huang 	switch (event) {
2957725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELRPORT:
2967725ccfdSJing Huang 		if (port->num_rports == 0) {
297a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
298a36c61f9SKrishna Gudipati 			bfa_fcs_lport_deleted(port);
2997725ccfdSJing Huang 		}
3007725ccfdSJing Huang 		break;
3017725ccfdSJing Huang 
3027725ccfdSJing Huang 	default:
303e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
3047725ccfdSJing Huang 	}
3057725ccfdSJing Huang }
3067725ccfdSJing Huang 
3075fbe25c7SJing Huang /*
3087725ccfdSJing Huang  *  fcs_port_pvt
3097725ccfdSJing Huang  */
3107725ccfdSJing Huang 
3117725ccfdSJing Huang /*
3127826f304SKrishna Gudipati  * Send AEN notification
3137826f304SKrishna Gudipati  */
3147826f304SKrishna Gudipati static void
3157826f304SKrishna Gudipati bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port,
3167826f304SKrishna Gudipati 			enum bfa_lport_aen_event event)
3177826f304SKrishna Gudipati {
3187826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
3197826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
3207826f304SKrishna Gudipati 
3217826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
3227826f304SKrishna Gudipati 	if (!aen_entry)
3237826f304SKrishna Gudipati 		return;
3247826f304SKrishna Gudipati 
3257826f304SKrishna Gudipati 	aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
3267826f304SKrishna Gudipati 	aen_entry->aen_data.lport.roles = port->port_cfg.roles;
3277826f304SKrishna Gudipati 	aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
3287826f304SKrishna Gudipati 					bfa_fcs_get_base_port(port->fcs));
3297826f304SKrishna Gudipati 	aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
3307826f304SKrishna Gudipati 
3317826f304SKrishna Gudipati 	/* Send the AEN notification */
3327826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
3337826f304SKrishna Gudipati 				  BFA_AEN_CAT_LPORT, event);
3347826f304SKrishna Gudipati }
3357826f304SKrishna Gudipati 
3367826f304SKrishna Gudipati /*
3377725ccfdSJing Huang  * Send a LS reject
3387725ccfdSJing Huang  */
3397725ccfdSJing Huang static void
340a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
3417725ccfdSJing Huang 			 u8 reason_code, u8 reason_code_expl)
3427725ccfdSJing Huang {
3437725ccfdSJing Huang 	struct fchs_s	fchs;
3447725ccfdSJing Huang 	struct bfa_fcxp_s *fcxp;
3457725ccfdSJing Huang 	struct bfa_rport_s *bfa_rport = NULL;
3467725ccfdSJing Huang 	int		len;
3477725ccfdSJing Huang 
348a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
3497725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
3507725ccfdSJing Huang 
351c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
3527725ccfdSJing Huang 	if (!fcxp)
3537725ccfdSJing Huang 		return;
3547725ccfdSJing Huang 
355a36c61f9SKrishna Gudipati 	len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
356a36c61f9SKrishna Gudipati 			      rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
357a36c61f9SKrishna Gudipati 			      rx_fchs->ox_id, reason_code, reason_code_expl);
3587725ccfdSJing Huang 
3597725ccfdSJing Huang 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
3607725ccfdSJing Huang 			  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
3617725ccfdSJing Huang 			  FC_MAX_PDUSZ, 0);
3627725ccfdSJing Huang }
3637725ccfdSJing Huang 
3645fbe25c7SJing Huang /*
365d7be54ccSKrishna Gudipati  * Send a FCCT Reject
366d7be54ccSKrishna Gudipati  */
367d7be54ccSKrishna Gudipati static void
368d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port,
369d7be54ccSKrishna Gudipati 	struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl)
370d7be54ccSKrishna Gudipati {
371d7be54ccSKrishna Gudipati 	struct fchs_s   fchs;
372d7be54ccSKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
373d7be54ccSKrishna Gudipati 	struct bfa_rport_s *bfa_rport = NULL;
374d7be54ccSKrishna Gudipati 	int             len;
375d7be54ccSKrishna Gudipati 	struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1);
376d7be54ccSKrishna Gudipati 	struct ct_hdr_s *ct_hdr;
377d7be54ccSKrishna Gudipati 
378d7be54ccSKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
379d7be54ccSKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
380d7be54ccSKrishna Gudipati 
381c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
382d7be54ccSKrishna Gudipati 	if (!fcxp)
383d7be54ccSKrishna Gudipati 		return;
384d7be54ccSKrishna Gudipati 
385d7be54ccSKrishna Gudipati 	ct_hdr = bfa_fcxp_get_reqbuf(fcxp);
386d7be54ccSKrishna Gudipati 	ct_hdr->gs_type = rx_cthdr->gs_type;
387d7be54ccSKrishna Gudipati 	ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type;
388d7be54ccSKrishna Gudipati 
389d7be54ccSKrishna Gudipati 	len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id,
390d7be54ccSKrishna Gudipati 			bfa_fcs_lport_get_fcid(port),
391d7be54ccSKrishna Gudipati 			rx_fchs->ox_id, reason_code, reason_code_expl);
392d7be54ccSKrishna Gudipati 
393d7be54ccSKrishna Gudipati 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
394d7be54ccSKrishna Gudipati 			BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
395d7be54ccSKrishna Gudipati 			FC_MAX_PDUSZ, 0);
396d7be54ccSKrishna Gudipati }
397d7be54ccSKrishna Gudipati 
398d7be54ccSKrishna Gudipati /*
3997725ccfdSJing Huang  * Process incoming plogi from a remote port.
4007725ccfdSJing Huang  */
4017725ccfdSJing Huang static void
402a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
403a36c61f9SKrishna Gudipati 		struct fchs_s *rx_fchs, struct fc_logi_s *plogi)
4047725ccfdSJing Huang {
4057725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
4067725ccfdSJing Huang 
4077725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->d_id);
4087725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
4097725ccfdSJing Huang 
4107725ccfdSJing Huang 	/*
4117725ccfdSJing Huang 	 * If min cfg mode is enabled, drop any incoming PLOGIs
4127725ccfdSJing Huang 	 */
4137725ccfdSJing Huang 	if (__fcs_min_cfg(port->fcs)) {
4147725ccfdSJing Huang 		bfa_trc(port->fcs, rx_fchs->s_id);
4157725ccfdSJing Huang 		return;
4167725ccfdSJing Huang 	}
4177725ccfdSJing Huang 
4187725ccfdSJing Huang 	if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
4197725ccfdSJing Huang 		bfa_trc(port->fcs, rx_fchs->s_id);
4207725ccfdSJing Huang 		/*
4217725ccfdSJing Huang 		 * send a LS reject
4227725ccfdSJing Huang 		 */
423a36c61f9SKrishna Gudipati 		bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
4247725ccfdSJing Huang 					FC_LS_RJT_RSN_PROTOCOL_ERROR,
4257725ccfdSJing Huang 					FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS);
4267725ccfdSJing Huang 		return;
4277725ccfdSJing Huang 	}
4287725ccfdSJing Huang 
4295fbe25c7SJing Huang 	/*
4307725ccfdSJing Huang 	 * Direct Attach P2P mode : verify address assigned by the r-port.
4317725ccfdSJing Huang 	 */
432a36c61f9SKrishna Gudipati 	if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
433a36c61f9SKrishna Gudipati 		(memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
434a36c61f9SKrishna Gudipati 			   (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
4357725ccfdSJing Huang 		if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
436a36c61f9SKrishna Gudipati 			/* Address assigned to us cannot be a WKA */
437a36c61f9SKrishna Gudipati 			bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
4387725ccfdSJing Huang 					FC_LS_RJT_RSN_PROTOCOL_ERROR,
4397725ccfdSJing Huang 					FC_LS_RJT_EXP_INVALID_NPORT_ID);
4407725ccfdSJing Huang 			return;
4417725ccfdSJing Huang 		}
4427725ccfdSJing Huang 		port->pid  = rx_fchs->d_id;
443b704495cSKrishna Gudipati 		bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
4447725ccfdSJing Huang 	}
4457725ccfdSJing Huang 
4465fbe25c7SJing Huang 	/*
4477725ccfdSJing Huang 	 * First, check if we know the device by pwwn.
4487725ccfdSJing Huang 	 */
449a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name);
4507725ccfdSJing Huang 	if (rport) {
4515fbe25c7SJing Huang 		/*
452a36c61f9SKrishna Gudipati 		 * Direct Attach P2P mode : handle address assigned by r-port.
4537725ccfdSJing Huang 		 */
454a36c61f9SKrishna Gudipati 		if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
455a36c61f9SKrishna Gudipati 			(memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
4567725ccfdSJing Huang 			(void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
4577725ccfdSJing Huang 			port->pid  = rx_fchs->d_id;
458b704495cSKrishna Gudipati 			bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
4597725ccfdSJing Huang 			rport->pid = rx_fchs->s_id;
4607725ccfdSJing Huang 		}
4617725ccfdSJing Huang 		bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
4627725ccfdSJing Huang 		return;
4637725ccfdSJing Huang 	}
4647725ccfdSJing Huang 
4655fbe25c7SJing Huang 	/*
4667725ccfdSJing Huang 	 * Next, lookup rport by PID.
4677725ccfdSJing Huang 	 */
468a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id);
4697725ccfdSJing Huang 	if (!rport) {
4705fbe25c7SJing Huang 		/*
4717725ccfdSJing Huang 		 * Inbound PLOGI from a new device.
4727725ccfdSJing Huang 		 */
4737725ccfdSJing Huang 		bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
4747725ccfdSJing Huang 		return;
4757725ccfdSJing Huang 	}
4767725ccfdSJing Huang 
4775fbe25c7SJing Huang 	/*
4787725ccfdSJing Huang 	 * Rport is known only by PID.
4797725ccfdSJing Huang 	 */
4807725ccfdSJing Huang 	if (rport->pwwn) {
4815fbe25c7SJing Huang 		/*
4827725ccfdSJing Huang 		 * This is a different device with the same pid. Old device
4837725ccfdSJing Huang 		 * disappeared. Send implicit LOGO to old device.
4847725ccfdSJing Huang 		 */
485d4b671c5SJing Huang 		WARN_ON(rport->pwwn == plogi->port_name);
486f7f73812SMaggie Zhang 		bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
4877725ccfdSJing Huang 
4885fbe25c7SJing Huang 		/*
4897725ccfdSJing Huang 		 * Inbound PLOGI from a new device (with old PID).
4907725ccfdSJing Huang 		 */
4917725ccfdSJing Huang 		bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
4927725ccfdSJing Huang 		return;
4937725ccfdSJing Huang 	}
4947725ccfdSJing Huang 
4955fbe25c7SJing Huang 	/*
4967725ccfdSJing Huang 	 * PLOGI crossing each other.
4977725ccfdSJing Huang 	 */
498d4b671c5SJing Huang 	WARN_ON(rport->pwwn != WWN_NULL);
4997725ccfdSJing Huang 	bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
5007725ccfdSJing Huang }
5017725ccfdSJing Huang 
5027725ccfdSJing Huang /*
5037725ccfdSJing Huang  * Process incoming ECHO.
5047725ccfdSJing Huang  * Since it does not require a login, it is processed here.
5057725ccfdSJing Huang  */
5067725ccfdSJing Huang static void
507a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
5087725ccfdSJing Huang 		struct fc_echo_s *echo, u16 rx_len)
5097725ccfdSJing Huang {
5107725ccfdSJing Huang 	struct fchs_s		fchs;
5117725ccfdSJing Huang 	struct bfa_fcxp_s	*fcxp;
5127725ccfdSJing Huang 	struct bfa_rport_s	*bfa_rport = NULL;
5137725ccfdSJing Huang 	int			len, pyld_len;
5147725ccfdSJing Huang 
5157725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
5167725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->d_id);
5177725ccfdSJing Huang 
518c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
5197725ccfdSJing Huang 	if (!fcxp)
5207725ccfdSJing Huang 		return;
5217725ccfdSJing Huang 
522a36c61f9SKrishna Gudipati 	len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
523a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
524a36c61f9SKrishna Gudipati 				rx_fchs->ox_id);
5257725ccfdSJing Huang 
5267725ccfdSJing Huang 	/*
5277725ccfdSJing Huang 	 * Copy the payload (if any) from the echo frame
5287725ccfdSJing Huang 	 */
5297725ccfdSJing Huang 	pyld_len = rx_len - sizeof(struct fchs_s);
530a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_len);
5317725ccfdSJing Huang 	bfa_trc(port->fcs, pyld_len);
5327725ccfdSJing Huang 
5337725ccfdSJing Huang 	if (pyld_len > len)
5347725ccfdSJing Huang 		memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
5357725ccfdSJing Huang 			sizeof(struct fc_echo_s), (echo + 1),
5367725ccfdSJing Huang 			(pyld_len - sizeof(struct fc_echo_s)));
5377725ccfdSJing Huang 
5387725ccfdSJing Huang 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
5397725ccfdSJing Huang 			BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
5407725ccfdSJing Huang 			FC_MAX_PDUSZ, 0);
5417725ccfdSJing Huang }
5427725ccfdSJing Huang 
5437725ccfdSJing Huang /*
5447725ccfdSJing Huang  * Process incoming RNID.
5457725ccfdSJing Huang  * Since it does not require a login, it is processed here.
5467725ccfdSJing Huang  */
5477725ccfdSJing Huang static void
548a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
5497725ccfdSJing Huang 		struct fc_rnid_cmd_s *rnid, u16 rx_len)
5507725ccfdSJing Huang {
5517725ccfdSJing Huang 	struct fc_rnid_common_id_data_s common_id_data;
5527725ccfdSJing Huang 	struct fc_rnid_general_topology_data_s gen_topo_data;
5537725ccfdSJing Huang 	struct fchs_s	fchs;
5547725ccfdSJing Huang 	struct bfa_fcxp_s *fcxp;
5557725ccfdSJing Huang 	struct bfa_rport_s *bfa_rport = NULL;
5567725ccfdSJing Huang 	u16	len;
5577725ccfdSJing Huang 	u32	data_format;
5587725ccfdSJing Huang 
5597725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
5607725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->d_id);
5617725ccfdSJing Huang 	bfa_trc(port->fcs, rx_len);
5627725ccfdSJing Huang 
563c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
5647725ccfdSJing Huang 	if (!fcxp)
5657725ccfdSJing Huang 		return;
5667725ccfdSJing Huang 
5677725ccfdSJing Huang 	/*
5687725ccfdSJing Huang 	 * Check Node Indentification Data Format
5697725ccfdSJing Huang 	 * We only support General Topology Discovery Format.
5707725ccfdSJing Huang 	 * For any other requested Data Formats, we return Common Node Id Data
5717725ccfdSJing Huang 	 * only, as per FC-LS.
5727725ccfdSJing Huang 	 */
5737725ccfdSJing Huang 	bfa_trc(port->fcs, rnid->node_id_data_format);
5747725ccfdSJing Huang 	if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
5757725ccfdSJing Huang 		data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
5767725ccfdSJing Huang 		/*
5777725ccfdSJing Huang 		 * Get General topology data for this port
5787725ccfdSJing Huang 		 */
5797725ccfdSJing Huang 		bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
5807725ccfdSJing Huang 	} else {
5817725ccfdSJing Huang 		data_format = RNID_NODEID_DATA_FORMAT_COMMON;
5827725ccfdSJing Huang 	}
5837725ccfdSJing Huang 
5847725ccfdSJing Huang 	/*
5857725ccfdSJing Huang 	 * Copy the Node Id Info
5867725ccfdSJing Huang 	 */
587a36c61f9SKrishna Gudipati 	common_id_data.port_name = bfa_fcs_lport_get_pwwn(port);
588a36c61f9SKrishna Gudipati 	common_id_data.node_name = bfa_fcs_lport_get_nwwn(port);
5897725ccfdSJing Huang 
590a36c61f9SKrishna Gudipati 	len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
591a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
592a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, data_format, &common_id_data,
593a36c61f9SKrishna Gudipati 				&gen_topo_data);
5947725ccfdSJing Huang 
5957725ccfdSJing Huang 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
5967725ccfdSJing Huang 			BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
5977725ccfdSJing Huang 			FC_MAX_PDUSZ, 0);
5987725ccfdSJing Huang }
5997725ccfdSJing Huang 
6007725ccfdSJing Huang /*
6017725ccfdSJing Huang  *  Fill out General Topolpgy Discovery Data for RNID ELS.
6027725ccfdSJing Huang  */
6037725ccfdSJing Huang static void
604a36c61f9SKrishna Gudipati bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
6057725ccfdSJing Huang 			struct fc_rnid_general_topology_data_s *gen_topo_data)
6067725ccfdSJing Huang {
6076a18b167SJing Huang 	memset(gen_topo_data, 0,
6087725ccfdSJing Huang 		      sizeof(struct fc_rnid_general_topology_data_s));
6097725ccfdSJing Huang 
610ba816ea8SJing Huang 	gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST);
6117725ccfdSJing Huang 	gen_topo_data->phy_port_num = 0;	/* @todo */
612ba816ea8SJing Huang 	gen_topo_data->num_attached_nodes = cpu_to_be32(1);
6137725ccfdSJing Huang }
6147725ccfdSJing Huang 
6157725ccfdSJing Huang static void
616a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
6177725ccfdSJing Huang {
618a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
619a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
620a36c61f9SKrishna Gudipati 
6217725ccfdSJing Huang 	bfa_trc(port->fcs, port->fabric->oper_type);
6227725ccfdSJing Huang 
6237725ccfdSJing Huang 	__port_action[port->fabric->fab_type].init(port);
6247725ccfdSJing Huang 	__port_action[port->fabric->fab_type].online(port);
6257725ccfdSJing Huang 
626a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
627a3f29cccSKrishna Gudipati 	BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
628a36c61f9SKrishna Gudipati 		"Logical port online: WWN = %s Role = %s\n",
629a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
6307826f304SKrishna Gudipati 	bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE);
631a36c61f9SKrishna Gudipati 
632a36c61f9SKrishna Gudipati 	bfad->bfad_flags |= BFAD_PORT_ONLINE;
6337725ccfdSJing Huang }
6347725ccfdSJing Huang 
6357725ccfdSJing Huang static void
636a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
6377725ccfdSJing Huang {
6387725ccfdSJing Huang 	struct list_head	*qe, *qen;
6397725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
640a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
641a36c61f9SKrishna Gudipati 	char    lpwwn_buf[BFA_STRING_32];
6427725ccfdSJing Huang 
6437725ccfdSJing Huang 	bfa_trc(port->fcs, port->fabric->oper_type);
6447725ccfdSJing Huang 
6457725ccfdSJing Huang 	__port_action[port->fabric->fab_type].offline(port);
6467725ccfdSJing Huang 
647a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
648f7f73812SMaggie Zhang 	if (bfa_sm_cmp_state(port->fabric,
6497826f304SKrishna Gudipati 			bfa_fcs_fabric_sm_online) == BFA_TRUE) {
650a3f29cccSKrishna Gudipati 		BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
651a36c61f9SKrishna Gudipati 		"Logical port lost fabric connectivity: WWN = %s Role = %s\n",
652a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
6537826f304SKrishna Gudipati 		bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
6547826f304SKrishna Gudipati 	} else {
655a3f29cccSKrishna Gudipati 		BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
656a36c61f9SKrishna Gudipati 		"Logical port taken offline: WWN = %s Role = %s\n",
657a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
6587826f304SKrishna Gudipati 		bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE);
6597826f304SKrishna Gudipati 	}
6607725ccfdSJing Huang 
6617725ccfdSJing Huang 	list_for_each_safe(qe, qen, &port->rport_q) {
6627725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
663f7f73812SMaggie Zhang 		bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
6647725ccfdSJing Huang 	}
6657725ccfdSJing Huang }
6667725ccfdSJing Huang 
6677725ccfdSJing Huang static void
668a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port)
6697725ccfdSJing Huang {
670d4b671c5SJing Huang 	WARN_ON(1);
6717725ccfdSJing Huang }
6727725ccfdSJing Huang 
6737725ccfdSJing Huang static void
674a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port)
6757725ccfdSJing Huang {
676d4b671c5SJing Huang 	WARN_ON(1);
6777725ccfdSJing Huang }
6787725ccfdSJing Huang 
6797725ccfdSJing Huang static void
680a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port)
6817725ccfdSJing Huang {
682d4b671c5SJing Huang 	WARN_ON(1);
6837725ccfdSJing Huang }
6847725ccfdSJing Huang 
6857725ccfdSJing Huang static void
686a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs)
6877725ccfdSJing Huang {
688a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
689a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
690a36c61f9SKrishna Gudipati 	int		len;
6917725ccfdSJing Huang 
692a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
693a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
694a36c61f9SKrishna Gudipati 
695c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
696a36c61f9SKrishna Gudipati 	if (!fcxp)
697a36c61f9SKrishna Gudipati 		return;
698a36c61f9SKrishna Gudipati 
699a36c61f9SKrishna Gudipati 	len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
700a36c61f9SKrishna Gudipati 			rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
701a36c61f9SKrishna Gudipati 			rx_fchs->ox_id, 0);
702a36c61f9SKrishna Gudipati 
703a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
704a36c61f9SKrishna Gudipati 			  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
705a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, 0);
706a36c61f9SKrishna Gudipati }
707a36c61f9SKrishna Gudipati static void
708a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
709a36c61f9SKrishna Gudipati {
710a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
711a36c61f9SKrishna Gudipati 	char    lpwwn_buf[BFA_STRING_32];
712a36c61f9SKrishna Gudipati 
713a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
71488166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
715a36c61f9SKrishna Gudipati 		"Logical port deleted: WWN = %s Role = %s\n",
716a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
7177826f304SKrishna Gudipati 	bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE);
718a36c61f9SKrishna Gudipati 
719a36c61f9SKrishna Gudipati 	/* Base port will be deleted by the OS driver */
72017c201b3SKrishna Gudipati 	if (port->vport)
7217725ccfdSJing Huang 		bfa_fcs_vport_delete_comp(port->vport);
72217c201b3SKrishna Gudipati 	else
723f7f73812SMaggie Zhang 		bfa_wc_down(&port->fabric->wc);
7247725ccfdSJing Huang }
7257725ccfdSJing Huang 
7267725ccfdSJing Huang 
7275fbe25c7SJing Huang /*
7287725ccfdSJing Huang  * Unsolicited frame receive handling.
7297725ccfdSJing Huang  */
7307725ccfdSJing Huang void
731a36c61f9SKrishna Gudipati bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
732a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
7337725ccfdSJing Huang {
7347725ccfdSJing Huang 	u32	pid = fchs->s_id;
7357725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport = NULL;
7367725ccfdSJing Huang 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
7377725ccfdSJing Huang 
7387725ccfdSJing Huang 	bfa_stats(lport, uf_recvs);
73915821f05SKrishna Gudipati 	bfa_trc(lport->fcs, fchs->type);
7407725ccfdSJing Huang 
741a36c61f9SKrishna Gudipati 	if (!bfa_fcs_lport_is_online(lport)) {
7427725ccfdSJing Huang 		bfa_stats(lport, uf_recv_drops);
7437725ccfdSJing Huang 		return;
7447725ccfdSJing Huang 	}
7457725ccfdSJing Huang 
7465fbe25c7SJing Huang 	/*
7477725ccfdSJing Huang 	 * First, handle ELSs that donot require a login.
7487725ccfdSJing Huang 	 */
7497725ccfdSJing Huang 	/*
7507725ccfdSJing Huang 	 * Handle PLOGI first
7517725ccfdSJing Huang 	 */
7527725ccfdSJing Huang 	if ((fchs->type == FC_TYPE_ELS) &&
7537725ccfdSJing Huang 		(els_cmd->els_code == FC_ELS_PLOGI)) {
754a36c61f9SKrishna Gudipati 		bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
7557725ccfdSJing Huang 		return;
7567725ccfdSJing Huang 	}
7577725ccfdSJing Huang 
7587725ccfdSJing Huang 	/*
7597725ccfdSJing Huang 	 * Handle ECHO separately.
7607725ccfdSJing Huang 	 */
7617725ccfdSJing Huang 	if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
762a36c61f9SKrishna Gudipati 		bfa_fcs_lport_echo(lport, fchs,
7637725ccfdSJing Huang 				(struct fc_echo_s *)els_cmd, len);
7647725ccfdSJing Huang 		return;
7657725ccfdSJing Huang 	}
7667725ccfdSJing Huang 
7677725ccfdSJing Huang 	/*
7687725ccfdSJing Huang 	 * Handle RNID separately.
7697725ccfdSJing Huang 	 */
7707725ccfdSJing Huang 	if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
771a36c61f9SKrishna Gudipati 		bfa_fcs_lport_rnid(lport, fchs,
7727725ccfdSJing Huang 			(struct fc_rnid_cmd_s *) els_cmd, len);
7737725ccfdSJing Huang 		return;
7747725ccfdSJing Huang 	}
7757725ccfdSJing Huang 
776a36c61f9SKrishna Gudipati 	if (fchs->type == FC_TYPE_BLS) {
777a36c61f9SKrishna Gudipati 		if ((fchs->routing == FC_RTG_BASIC_LINK) &&
778a36c61f9SKrishna Gudipati 				(fchs->cat_info == FC_CAT_ABTS))
779a36c61f9SKrishna Gudipati 			bfa_fcs_lport_abts_acc(lport, fchs);
780a36c61f9SKrishna Gudipati 		return;
781a36c61f9SKrishna Gudipati 	}
782d7be54ccSKrishna Gudipati 
783d7be54ccSKrishna Gudipati 	if (fchs->type == FC_TYPE_SERVICES) {
784d7be54ccSKrishna Gudipati 		/*
785d7be54ccSKrishna Gudipati 		 * Unhandled FC-GS frames. Send a FC-CT Reject
786d7be54ccSKrishna Gudipati 		 */
787d7be54ccSKrishna Gudipati 		bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP,
788d7be54ccSKrishna Gudipati 				CT_NS_EXP_NOADDITIONAL);
789d7be54ccSKrishna Gudipati 		return;
790d7be54ccSKrishna Gudipati 	}
791d7be54ccSKrishna Gudipati 
7925fbe25c7SJing Huang 	/*
7937725ccfdSJing Huang 	 * look for a matching remote port ID
7947725ccfdSJing Huang 	 */
795a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pid(lport, pid);
7967725ccfdSJing Huang 	if (rport) {
7977725ccfdSJing Huang 		bfa_trc(rport->fcs, fchs->s_id);
7987725ccfdSJing Huang 		bfa_trc(rport->fcs, fchs->d_id);
7997725ccfdSJing Huang 		bfa_trc(rport->fcs, fchs->type);
8007725ccfdSJing Huang 
8017725ccfdSJing Huang 		bfa_fcs_rport_uf_recv(rport, fchs, len);
8027725ccfdSJing Huang 		return;
8037725ccfdSJing Huang 	}
8047725ccfdSJing Huang 
8055fbe25c7SJing Huang 	/*
8067725ccfdSJing Huang 	 * Only handles ELS frames for now.
8077725ccfdSJing Huang 	 */
8087725ccfdSJing Huang 	if (fchs->type != FC_TYPE_ELS) {
80915821f05SKrishna Gudipati 		bfa_trc(lport->fcs, fchs->s_id);
81015821f05SKrishna Gudipati 		bfa_trc(lport->fcs, fchs->d_id);
81115821f05SKrishna Gudipati 		/* ignore type FC_TYPE_FC_FSS */
81215821f05SKrishna Gudipati 		if (fchs->type != FC_TYPE_FC_FSS)
81315821f05SKrishna Gudipati 			bfa_sm_fault(lport->fcs, fchs->type);
8147725ccfdSJing Huang 		return;
8157725ccfdSJing Huang 	}
8167725ccfdSJing Huang 
8177725ccfdSJing Huang 	bfa_trc(lport->fcs, els_cmd->els_code);
8187725ccfdSJing Huang 	if (els_cmd->els_code == FC_ELS_RSCN) {
819a36c61f9SKrishna Gudipati 		bfa_fcs_lport_scn_process_rscn(lport, fchs, len);
8207725ccfdSJing Huang 		return;
8217725ccfdSJing Huang 	}
8227725ccfdSJing Huang 
8237725ccfdSJing Huang 	if (els_cmd->els_code == FC_ELS_LOGO) {
8245fbe25c7SJing Huang 		/*
8257725ccfdSJing Huang 		 * @todo Handle LOGO frames received.
8267725ccfdSJing Huang 		 */
8277725ccfdSJing Huang 		return;
8287725ccfdSJing Huang 	}
8297725ccfdSJing Huang 
8307725ccfdSJing Huang 	if (els_cmd->els_code == FC_ELS_PRLI) {
8315fbe25c7SJing Huang 		/*
8327725ccfdSJing Huang 		 * @todo Handle PRLI frames received.
8337725ccfdSJing Huang 		 */
8347725ccfdSJing Huang 		return;
8357725ccfdSJing Huang 	}
8367725ccfdSJing Huang 
8375fbe25c7SJing Huang 	/*
8387725ccfdSJing Huang 	 * Unhandled ELS frames. Send a LS_RJT.
8397725ccfdSJing Huang 	 */
840a36c61f9SKrishna Gudipati 	bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
8417725ccfdSJing Huang 				 FC_LS_RJT_EXP_NO_ADDL_INFO);
8427725ccfdSJing Huang 
8437725ccfdSJing Huang }
8447725ccfdSJing Huang 
8455fbe25c7SJing Huang /*
8467725ccfdSJing Huang  *   PID based Lookup for a R-Port in the Port R-Port Queue
8477725ccfdSJing Huang  */
8487725ccfdSJing Huang struct bfa_fcs_rport_s *
849a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid)
8507725ccfdSJing Huang {
8517725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
8527725ccfdSJing Huang 	struct list_head	*qe;
8537725ccfdSJing Huang 
8547725ccfdSJing Huang 	list_for_each(qe, &port->rport_q) {
8557725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
8567725ccfdSJing Huang 		if (rport->pid == pid)
8577725ccfdSJing Huang 			return rport;
8587725ccfdSJing Huang 	}
8597725ccfdSJing Huang 
8607725ccfdSJing Huang 	bfa_trc(port->fcs, pid);
8617725ccfdSJing Huang 	return NULL;
8627725ccfdSJing Huang }
8637725ccfdSJing Huang 
8645fbe25c7SJing Huang /*
865ee1a4a42SKrishna Gudipati  * OLD_PID based Lookup for a R-Port in the Port R-Port Queue
866ee1a4a42SKrishna Gudipati  */
867ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s *
868ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_by_old_pid(struct bfa_fcs_lport_s *port, u32 pid)
869ee1a4a42SKrishna Gudipati {
870ee1a4a42SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
871ee1a4a42SKrishna Gudipati 	struct list_head	*qe;
872ee1a4a42SKrishna Gudipati 
873ee1a4a42SKrishna Gudipati 	list_for_each(qe, &port->rport_q) {
874ee1a4a42SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
875ee1a4a42SKrishna Gudipati 		if (rport->old_pid == pid)
876ee1a4a42SKrishna Gudipati 			return rport;
877ee1a4a42SKrishna Gudipati 	}
878ee1a4a42SKrishna Gudipati 
879ee1a4a42SKrishna Gudipati 	bfa_trc(port->fcs, pid);
880ee1a4a42SKrishna Gudipati 	return NULL;
881ee1a4a42SKrishna Gudipati }
882ee1a4a42SKrishna Gudipati 
883ee1a4a42SKrishna Gudipati /*
8847725ccfdSJing Huang  *   PWWN based Lookup for a R-Port in the Port R-Port Queue
8857725ccfdSJing Huang  */
8867725ccfdSJing Huang struct bfa_fcs_rport_s *
887a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn)
8887725ccfdSJing Huang {
8897725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
8907725ccfdSJing Huang 	struct list_head	*qe;
8917725ccfdSJing Huang 
8927725ccfdSJing Huang 	list_for_each(qe, &port->rport_q) {
8937725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
8947725ccfdSJing Huang 		if (wwn_is_equal(rport->pwwn, pwwn))
8957725ccfdSJing Huang 			return rport;
8967725ccfdSJing Huang 	}
8977725ccfdSJing Huang 
8987725ccfdSJing Huang 	bfa_trc(port->fcs, pwwn);
899f8ceafdeSJing Huang 	return NULL;
9007725ccfdSJing Huang }
9017725ccfdSJing Huang 
9025fbe25c7SJing Huang /*
9037725ccfdSJing Huang  *   NWWN based Lookup for a R-Port in the Port R-Port Queue
9047725ccfdSJing Huang  */
9057725ccfdSJing Huang struct bfa_fcs_rport_s *
906a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn)
9077725ccfdSJing Huang {
9087725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
9097725ccfdSJing Huang 	struct list_head	*qe;
9107725ccfdSJing Huang 
9117725ccfdSJing Huang 	list_for_each(qe, &port->rport_q) {
9127725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
9137725ccfdSJing Huang 		if (wwn_is_equal(rport->nwwn, nwwn))
9147725ccfdSJing Huang 			return rport;
9157725ccfdSJing Huang 	}
9167725ccfdSJing Huang 
9177725ccfdSJing Huang 	bfa_trc(port->fcs, nwwn);
918f8ceafdeSJing Huang 	return NULL;
9197725ccfdSJing Huang }
9207725ccfdSJing Huang 
9215fbe25c7SJing Huang /*
922ee1a4a42SKrishna Gudipati  * PWWN & PID based Lookup for a R-Port in the Port R-Port Queue
923ee1a4a42SKrishna Gudipati  */
924ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s *
925ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_by_qualifier(struct bfa_fcs_lport_s *port,
926ee1a4a42SKrishna Gudipati 				     wwn_t pwwn, u32 pid)
927ee1a4a42SKrishna Gudipati {
928ee1a4a42SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
929ee1a4a42SKrishna Gudipati 	struct list_head	*qe;
930ee1a4a42SKrishna Gudipati 
931ee1a4a42SKrishna Gudipati 	list_for_each(qe, &port->rport_q) {
932ee1a4a42SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
933ee1a4a42SKrishna Gudipati 		if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid)
934ee1a4a42SKrishna Gudipati 			return rport;
935ee1a4a42SKrishna Gudipati 	}
936ee1a4a42SKrishna Gudipati 
937ee1a4a42SKrishna Gudipati 	bfa_trc(port->fcs, pwwn);
938ee1a4a42SKrishna Gudipati 	return NULL;
939ee1a4a42SKrishna Gudipati }
940ee1a4a42SKrishna Gudipati 
941ee1a4a42SKrishna Gudipati /*
9427725ccfdSJing Huang  * Called by rport module when new rports are discovered.
9437725ccfdSJing Huang  */
9447725ccfdSJing Huang void
945a36c61f9SKrishna Gudipati bfa_fcs_lport_add_rport(
946a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
9477725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport)
9487725ccfdSJing Huang {
9497725ccfdSJing Huang 	list_add_tail(&rport->qe, &port->rport_q);
9507725ccfdSJing Huang 	port->num_rports++;
9517725ccfdSJing Huang }
9527725ccfdSJing Huang 
9535fbe25c7SJing Huang /*
9547725ccfdSJing Huang  * Called by rport module to when rports are deleted.
9557725ccfdSJing Huang  */
9567725ccfdSJing Huang void
957a36c61f9SKrishna Gudipati bfa_fcs_lport_del_rport(
958a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
9597725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport)
9607725ccfdSJing Huang {
961d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport));
9627725ccfdSJing Huang 	list_del(&rport->qe);
9637725ccfdSJing Huang 	port->num_rports--;
9647725ccfdSJing Huang 
9657725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
9667725ccfdSJing Huang }
9677725ccfdSJing Huang 
9685fbe25c7SJing Huang /*
9697725ccfdSJing Huang  * Called by fabric for base port when fabric login is complete.
9707725ccfdSJing Huang  * Called by vport for virtual ports when FDISC is complete.
9717725ccfdSJing Huang  */
9727725ccfdSJing Huang void
973a36c61f9SKrishna Gudipati bfa_fcs_lport_online(struct bfa_fcs_lport_s *port)
9747725ccfdSJing Huang {
9757725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
9767725ccfdSJing Huang }
9777725ccfdSJing Huang 
9785fbe25c7SJing Huang /*
9797725ccfdSJing Huang  * Called by fabric for base port when fabric goes offline.
9807725ccfdSJing Huang  * Called by vport for virtual ports when virtual port becomes offline.
9817725ccfdSJing Huang  */
9827725ccfdSJing Huang void
983a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port)
9847725ccfdSJing Huang {
9857725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
9867725ccfdSJing Huang }
9877725ccfdSJing Huang 
9885fbe25c7SJing Huang /*
989881c1b3cSKrishna Gudipati  * Called by fabric for base port and by vport for virtual ports
990881c1b3cSKrishna Gudipati  * when target mode driver is unloaded.
991881c1b3cSKrishna Gudipati  */
992881c1b3cSKrishna Gudipati void
993881c1b3cSKrishna Gudipati bfa_fcs_lport_stop(struct bfa_fcs_lport_s *port)
994881c1b3cSKrishna Gudipati {
995881c1b3cSKrishna Gudipati 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_STOP);
996881c1b3cSKrishna Gudipati }
997881c1b3cSKrishna Gudipati 
998881c1b3cSKrishna Gudipati /*
9997725ccfdSJing Huang  * Called by fabric to delete base lport and associated resources.
10007725ccfdSJing Huang  *
10017725ccfdSJing Huang  * Called by vport to delete lport and associated resources. Should call
10027725ccfdSJing Huang  * bfa_fcs_vport_delete_comp() for vports on completion.
10037725ccfdSJing Huang  */
10047725ccfdSJing Huang void
1005a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port)
10067725ccfdSJing Huang {
10077725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
10087725ccfdSJing Huang }
10097725ccfdSJing Huang 
10105fbe25c7SJing Huang /*
10117725ccfdSJing Huang  * Return TRUE if port is online, else return FALSE
10127725ccfdSJing Huang  */
10137725ccfdSJing Huang bfa_boolean_t
1014a36c61f9SKrishna Gudipati bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port)
10157725ccfdSJing Huang {
1016a36c61f9SKrishna Gudipati 	return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online);
10177725ccfdSJing Huang }
10187725ccfdSJing Huang 
10195fbe25c7SJing Huang /*
1020e6714324SKrishna Gudipati   * Attach time initialization of logical ports.
10217725ccfdSJing Huang  */
10227725ccfdSJing Huang void
1023a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs,
1024a36c61f9SKrishna Gudipati 		   u16 vf_id, struct bfa_fcs_vport_s *vport)
10257725ccfdSJing Huang {
10267725ccfdSJing Huang 	lport->fcs = fcs;
10277725ccfdSJing Huang 	lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
10287725ccfdSJing Huang 	lport->vport = vport;
10293fd45980SKrishna Gudipati 	lport->lp_tag = (vport) ? vport->lps->bfa_tag :
10303fd45980SKrishna Gudipati 				  lport->fabric->lps->bfa_tag;
10317725ccfdSJing Huang 
10327725ccfdSJing Huang 	INIT_LIST_HEAD(&lport->rport_q);
10337725ccfdSJing Huang 	lport->num_rports = 0;
1034e6714324SKrishna Gudipati }
10357725ccfdSJing Huang 
10365fbe25c7SJing Huang /*
1037e6714324SKrishna Gudipati  * Logical port initialization of base or virtual port.
1038e6714324SKrishna Gudipati  * Called by fabric for base port or by vport for virtual ports.
1039e6714324SKrishna Gudipati  */
1040e6714324SKrishna Gudipati 
1041e6714324SKrishna Gudipati void
1042a36c61f9SKrishna Gudipati bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
1043a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg)
1044e6714324SKrishna Gudipati {
1045e6714324SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = lport->vport;
1046a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad;
1047a36c61f9SKrishna Gudipati 	char    lpwwn_buf[BFA_STRING_32];
1048e6714324SKrishna Gudipati 
10496a18b167SJing Huang 	lport->port_cfg = *port_cfg;
1050e6714324SKrishna Gudipati 
1051a36c61f9SKrishna Gudipati 	lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport,
1052e6714324SKrishna Gudipati 					lport->port_cfg.roles,
10537725ccfdSJing Huang 					lport->fabric->vf_drv,
10547725ccfdSJing Huang 					vport ? vport->vport_drv : NULL);
1055e6714324SKrishna Gudipati 
1056a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport));
105788166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
1058a36c61f9SKrishna Gudipati 		"New logical port created: WWN = %s Role = %s\n",
1059a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
10607826f304SKrishna Gudipati 	bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW);
10617725ccfdSJing Huang 
1062a36c61f9SKrishna Gudipati 	bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit);
10637725ccfdSJing Huang 	bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
10647725ccfdSJing Huang }
10657725ccfdSJing Huang 
10665fbe25c7SJing Huang /*
10677725ccfdSJing Huang  *  fcs_lport_api
10687725ccfdSJing Huang  */
10697725ccfdSJing Huang 
10707725ccfdSJing Huang void
1071a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr(
1072a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
1073a36c61f9SKrishna Gudipati 	struct bfa_lport_attr_s *port_attr)
10747725ccfdSJing Huang {
1075a36c61f9SKrishna Gudipati 	if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
10767725ccfdSJing Huang 		port_attr->pid = port->pid;
10777725ccfdSJing Huang 	else
10787725ccfdSJing Huang 		port_attr->pid = 0;
10797725ccfdSJing Huang 
10807725ccfdSJing Huang 	port_attr->port_cfg = port->port_cfg;
10817725ccfdSJing Huang 
10827725ccfdSJing Huang 	if (port->fabric) {
1083f7f73812SMaggie Zhang 		port_attr->port_type = port->fabric->oper_type;
1084da99dcc9SMaggie Zhang 		port_attr->loopback = bfa_sm_cmp_state(port->fabric,
1085da99dcc9SMaggie Zhang 				bfa_fcs_fabric_sm_loopback);
1086f926a05fSKrishna Gudipati 		port_attr->authfail =
1087f7f73812SMaggie Zhang 			bfa_sm_cmp_state(port->fabric,
1088f7f73812SMaggie Zhang 				bfa_fcs_fabric_sm_auth_failed);
1089a36c61f9SKrishna Gudipati 		port_attr->fabric_name  = bfa_fcs_lport_get_fabric_name(port);
10907725ccfdSJing Huang 		memcpy(port_attr->fabric_ip_addr,
1091a36c61f9SKrishna Gudipati 			bfa_fcs_lport_get_fabric_ipaddr(port),
10927725ccfdSJing Huang 			BFA_FCS_FABRIC_IPADDR_SZ);
10937725ccfdSJing Huang 
109486e32dabSKrishna Gudipati 		if (port->vport != NULL) {
1095a36c61f9SKrishna Gudipati 			port_attr->port_type = BFA_PORT_TYPE_VPORT;
109686e32dabSKrishna Gudipati 			port_attr->fpma_mac =
1097f7f73812SMaggie Zhang 				port->vport->lps->lp_mac;
1098a36c61f9SKrishna Gudipati 		} else {
109986e32dabSKrishna Gudipati 			port_attr->fpma_mac =
1100f7f73812SMaggie Zhang 				port->fabric->lps->lp_mac;
1101a36c61f9SKrishna Gudipati 		}
1102a36c61f9SKrishna Gudipati 	} else {
1103a36c61f9SKrishna Gudipati 		port_attr->port_type = BFA_PORT_TYPE_UNKNOWN;
1104a36c61f9SKrishna Gudipati 		port_attr->state = BFA_LPORT_UNINIT;
1105a36c61f9SKrishna Gudipati 	}
1106a36c61f9SKrishna Gudipati }
1107a36c61f9SKrishna Gudipati 
11085fbe25c7SJing Huang /*
1109a36c61f9SKrishna Gudipati  *  bfa_fcs_lport_fab port fab functions
1110a36c61f9SKrishna Gudipati  */
1111a36c61f9SKrishna Gudipati 
11125fbe25c7SJing Huang /*
1113a36c61f9SKrishna Gudipati  *   Called by port to initialize fabric services of the base port.
1114a36c61f9SKrishna Gudipati  */
1115a36c61f9SKrishna Gudipati static void
1116a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port)
1117a36c61f9SKrishna Gudipati {
1118a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ns_init(port);
1119a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_init(port);
1120a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ms_init(port);
1121a36c61f9SKrishna Gudipati }
1122a36c61f9SKrishna Gudipati 
11235fbe25c7SJing Huang /*
1124a36c61f9SKrishna Gudipati  *   Called by port to notify transition to online state.
1125a36c61f9SKrishna Gudipati  */
1126a36c61f9SKrishna Gudipati static void
1127a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
1128a36c61f9SKrishna Gudipati {
1129a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ns_online(port);
1130a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_online(port);
1131a36c61f9SKrishna Gudipati }
1132a36c61f9SKrishna Gudipati 
11335fbe25c7SJing Huang /*
1134a36c61f9SKrishna Gudipati  *   Called by port to notify transition to offline state.
1135a36c61f9SKrishna Gudipati  */
1136a36c61f9SKrishna Gudipati static void
1137a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port)
1138a36c61f9SKrishna Gudipati {
1139a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ns_offline(port);
1140a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_offline(port);
1141a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ms_offline(port);
1142a36c61f9SKrishna Gudipati }
1143a36c61f9SKrishna Gudipati 
11445fbe25c7SJing Huang /*
1145a36c61f9SKrishna Gudipati  *  bfa_fcs_lport_n2n  functions
1146a36c61f9SKrishna Gudipati  */
1147a36c61f9SKrishna Gudipati 
11485fbe25c7SJing Huang /*
1149a36c61f9SKrishna Gudipati  *   Called by fcs/port to initialize N2N topology.
1150a36c61f9SKrishna Gudipati  */
1151a36c61f9SKrishna Gudipati static void
1152a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port)
1153a36c61f9SKrishna Gudipati {
1154a36c61f9SKrishna Gudipati }
1155a36c61f9SKrishna Gudipati 
11565fbe25c7SJing Huang /*
1157a36c61f9SKrishna Gudipati  *   Called by fcs/port to notify transition to online state.
1158a36c61f9SKrishna Gudipati  */
1159a36c61f9SKrishna Gudipati static void
1160a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
1161a36c61f9SKrishna Gudipati {
1162a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1163a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *pcfg = &port->port_cfg;
1164a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
1165a36c61f9SKrishna Gudipati 
1166a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, pcfg->pwwn);
1167a36c61f9SKrishna Gudipati 
1168a36c61f9SKrishna Gudipati 	/*
1169a36c61f9SKrishna Gudipati 	 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
1170a36c61f9SKrishna Gudipati 	 * and assign an Address. if not, we need to wait for its PLOGI.
1171a36c61f9SKrishna Gudipati 	 *
1172a36c61f9SKrishna Gudipati 	 * If our PWWN is < than that of the remote port, it will send a PLOGI
1173a36c61f9SKrishna Gudipati 	 * with the PIDs assigned. The rport state machine take care of this
1174a36c61f9SKrishna Gudipati 	 * incoming PLOGI.
1175a36c61f9SKrishna Gudipati 	 */
1176a36c61f9SKrishna Gudipati 	if (memcmp
1177a36c61f9SKrishna Gudipati 	    ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
1178a36c61f9SKrishna Gudipati 	     sizeof(wwn_t)) > 0) {
1179a36c61f9SKrishna Gudipati 		port->pid = N2N_LOCAL_PID;
1180b704495cSKrishna Gudipati 		bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID);
11815fbe25c7SJing Huang 		/*
1182a36c61f9SKrishna Gudipati 		 * First, check if we know the device by pwwn.
1183a36c61f9SKrishna Gudipati 		 */
1184a36c61f9SKrishna Gudipati 		rport = bfa_fcs_lport_get_rport_by_pwwn(port,
1185a36c61f9SKrishna Gudipati 							n2n_port->rem_port_wwn);
1186a36c61f9SKrishna Gudipati 		if (rport) {
1187a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rport->pid);
1188a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rport->pwwn);
1189a36c61f9SKrishna Gudipati 			rport->pid = N2N_REMOTE_PID;
1190f7f73812SMaggie Zhang 			bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
1191a36c61f9SKrishna Gudipati 			return;
1192a36c61f9SKrishna Gudipati 		}
1193a36c61f9SKrishna Gudipati 
1194a36c61f9SKrishna Gudipati 		/*
1195a36c61f9SKrishna Gudipati 		 * In n2n there can be only one rport. Delete the old one
1196a36c61f9SKrishna Gudipati 		 * whose pid should be zero, because it is offline.
1197a36c61f9SKrishna Gudipati 		 */
1198a36c61f9SKrishna Gudipati 		if (port->num_rports > 0) {
1199a36c61f9SKrishna Gudipati 			rport = bfa_fcs_lport_get_rport_by_pid(port, 0);
1200d4b671c5SJing Huang 			WARN_ON(rport == NULL);
1201a36c61f9SKrishna Gudipati 			if (rport) {
1202a36c61f9SKrishna Gudipati 				bfa_trc(port->fcs, rport->pwwn);
1203f7f73812SMaggie Zhang 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1204a36c61f9SKrishna Gudipati 			}
1205a36c61f9SKrishna Gudipati 		}
1206a36c61f9SKrishna Gudipati 		bfa_fcs_rport_create(port, N2N_REMOTE_PID);
1207a36c61f9SKrishna Gudipati 	}
1208a36c61f9SKrishna Gudipati }
1209a36c61f9SKrishna Gudipati 
12105fbe25c7SJing Huang /*
1211a36c61f9SKrishna Gudipati  *   Called by fcs/port to notify transition to offline state.
1212a36c61f9SKrishna Gudipati  */
1213a36c61f9SKrishna Gudipati static void
1214a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
1215a36c61f9SKrishna Gudipati {
1216a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1217a36c61f9SKrishna Gudipati 
1218a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
1219a36c61f9SKrishna Gudipati 	port->pid = 0;
1220a36c61f9SKrishna Gudipati 	n2n_port->rem_port_wwn = 0;
1221a36c61f9SKrishna Gudipati 	n2n_port->reply_oxid = 0;
1222a36c61f9SKrishna Gudipati }
1223a36c61f9SKrishna Gudipati 
1224a36c61f9SKrishna Gudipati #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
1225a36c61f9SKrishna Gudipati 
1226a36c61f9SKrishna Gudipati /*
1227a36c61f9SKrishna Gudipati  * forward declarations
1228a36c61f9SKrishna Gudipati  */
1229a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg,
1230a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
1231a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg,
1232a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
1233a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg,
1234a36c61f9SKrishna Gudipati 					   struct bfa_fcxp_s *fcxp_alloced);
1235a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_rhba_response(void *fcsarg,
1236a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
1237a36c61f9SKrishna Gudipati 						void *cbarg,
1238a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
1239a36c61f9SKrishna Gudipati 						u32 rsp_len,
1240a36c61f9SKrishna Gudipati 						u32 resid_len,
1241a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
1242a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_rprt_response(void *fcsarg,
1243a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
1244a36c61f9SKrishna Gudipati 						void *cbarg,
1245a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
1246a36c61f9SKrishna Gudipati 						u32 rsp_len,
1247a36c61f9SKrishna Gudipati 						u32 resid_len,
1248a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
1249a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_rpa_response(void *fcsarg,
1250a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
1251a36c61f9SKrishna Gudipati 					       void *cbarg,
1252a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
1253a36c61f9SKrishna Gudipati 					       u32 rsp_len,
1254a36c61f9SKrishna Gudipati 					       u32 resid_len,
1255a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
1256a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_timeout(void *arg);
1257a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1258a36c61f9SKrishna Gudipati 						  u8 *pyld);
1259a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1260a36c61f9SKrishna Gudipati 						  u8 *pyld);
1261a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1262a36c61f9SKrishna Gudipati 						 u8 *pyld);
1263a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *
1264a36c61f9SKrishna Gudipati 						       fdmi, u8 *pyld);
1265a36c61f9SKrishna Gudipati static void	bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1266a36c61f9SKrishna Gudipati 				 struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
1267a36c61f9SKrishna Gudipati static void	bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1268a36c61f9SKrishna Gudipati 				  struct bfa_fcs_fdmi_port_attr_s *port_attr);
1269d7be54ccSKrishna Gudipati u32	bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed);
1270d7be54ccSKrishna Gudipati 
12715fbe25c7SJing Huang /*
1272a36c61f9SKrishna Gudipati  *  fcs_fdmi_sm FCS FDMI state machine
1273a36c61f9SKrishna Gudipati  */
1274a36c61f9SKrishna Gudipati 
12755fbe25c7SJing Huang /*
1276a36c61f9SKrishna Gudipati  *  FDMI State Machine events
1277a36c61f9SKrishna Gudipati  */
1278a36c61f9SKrishna Gudipati enum port_fdmi_event {
1279a36c61f9SKrishna Gudipati 	FDMISM_EVENT_PORT_ONLINE = 1,
1280a36c61f9SKrishna Gudipati 	FDMISM_EVENT_PORT_OFFLINE = 2,
1281a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RSP_OK = 4,
1282a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RSP_ERROR = 5,
1283a36c61f9SKrishna Gudipati 	FDMISM_EVENT_TIMEOUT = 6,
1284a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RHBA_SENT = 7,
1285a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RPRT_SENT = 8,
1286a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RPA_SENT = 9,
1287a36c61f9SKrishna Gudipati };
1288a36c61f9SKrishna Gudipati 
1289a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1290a36c61f9SKrishna Gudipati 					     enum port_fdmi_event event);
1291a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_sending_rhba(
1292a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1293a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1294a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1295a36c61f9SKrishna Gudipati 					  enum port_fdmi_event event);
1296a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rhba_retry(
1297a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1298a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1299a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_sending_rprt(
1300a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1301a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1302a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1303a36c61f9SKrishna Gudipati 					  enum port_fdmi_event event);
1304a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rprt_retry(
1305a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1306a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1307a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_sending_rpa(
1308a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1309a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1310a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1311a36c61f9SKrishna Gudipati 					 enum port_fdmi_event event);
1312a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rpa_retry(
1313a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1314a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1315a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1316a36c61f9SKrishna Gudipati 					    enum port_fdmi_event event);
1317a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_disabled(
1318a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1319a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
13205fbe25c7SJing Huang /*
1321a36c61f9SKrishna Gudipati  *	Start in offline state - awaiting MS to send start.
1322a36c61f9SKrishna Gudipati  */
1323a36c61f9SKrishna Gudipati static void
1324a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1325a36c61f9SKrishna Gudipati 			     enum port_fdmi_event event)
1326a36c61f9SKrishna Gudipati {
1327a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1328a36c61f9SKrishna Gudipati 
1329a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1330a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1331a36c61f9SKrishna Gudipati 
1332a36c61f9SKrishna Gudipati 	fdmi->retry_cnt = 0;
1333a36c61f9SKrishna Gudipati 
1334a36c61f9SKrishna Gudipati 	switch (event) {
1335a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_ONLINE:
1336a36c61f9SKrishna Gudipati 		if (port->vport) {
1337a36c61f9SKrishna Gudipati 			/*
1338a36c61f9SKrishna Gudipati 			 * For Vports, register a new port.
1339a36c61f9SKrishna Gudipati 			 */
1340a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1341a36c61f9SKrishna Gudipati 					 bfa_fcs_lport_fdmi_sm_sending_rprt);
1342a36c61f9SKrishna Gudipati 			bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1343a36c61f9SKrishna Gudipati 		} else {
1344a36c61f9SKrishna Gudipati 			/*
1345a36c61f9SKrishna Gudipati 			 * For a base port, we should first register the HBA
134625985edcSLucas De Marchi 			 * attribute. The HBA attribute also contains the base
1347a36c61f9SKrishna Gudipati 			 *  port registration.
1348a36c61f9SKrishna Gudipati 			 */
1349a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1350a36c61f9SKrishna Gudipati 					 bfa_fcs_lport_fdmi_sm_sending_rhba);
1351a36c61f9SKrishna Gudipati 			bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1352a36c61f9SKrishna Gudipati 		}
1353a36c61f9SKrishna Gudipati 		break;
1354a36c61f9SKrishna Gudipati 
1355a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1356a36c61f9SKrishna Gudipati 		break;
1357a36c61f9SKrishna Gudipati 
1358a36c61f9SKrishna Gudipati 	default:
1359a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1360a36c61f9SKrishna Gudipati 	}
1361a36c61f9SKrishna Gudipati }
1362a36c61f9SKrishna Gudipati 
1363a36c61f9SKrishna Gudipati static void
1364a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1365a36c61f9SKrishna Gudipati 				  enum port_fdmi_event event)
1366a36c61f9SKrishna Gudipati {
1367a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1368a36c61f9SKrishna Gudipati 
1369a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1370a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1371a36c61f9SKrishna Gudipati 
1372a36c61f9SKrishna Gudipati 	switch (event) {
1373a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RHBA_SENT:
1374a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba);
1375a36c61f9SKrishna Gudipati 		break;
1376a36c61f9SKrishna Gudipati 
1377a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1378a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1379a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1380a36c61f9SKrishna Gudipati 					   &fdmi->fcxp_wqe);
1381a36c61f9SKrishna Gudipati 		break;
1382a36c61f9SKrishna Gudipati 
1383a36c61f9SKrishna Gudipati 	default:
1384a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1385a36c61f9SKrishna Gudipati 	}
1386a36c61f9SKrishna Gudipati }
1387a36c61f9SKrishna Gudipati 
1388a36c61f9SKrishna Gudipati static void
1389a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1390a36c61f9SKrishna Gudipati 			enum port_fdmi_event event)
1391a36c61f9SKrishna Gudipati {
1392a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1393a36c61f9SKrishna Gudipati 
1394a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1395a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1396a36c61f9SKrishna Gudipati 
1397a36c61f9SKrishna Gudipati 	switch (event) {
1398a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_ERROR:
1399a36c61f9SKrishna Gudipati 		/*
1400a36c61f9SKrishna Gudipati 		 * if max retries have not been reached, start timer for a
1401a36c61f9SKrishna Gudipati 		 * delayed retry
1402a36c61f9SKrishna Gudipati 		 */
1403a36c61f9SKrishna Gudipati 		if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1404a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1405a36c61f9SKrishna Gudipati 					bfa_fcs_lport_fdmi_sm_rhba_retry);
1406a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1407a36c61f9SKrishna Gudipati 					    &fdmi->timer,
1408a36c61f9SKrishna Gudipati 					    bfa_fcs_lport_fdmi_timeout, fdmi,
1409a36c61f9SKrishna Gudipati 					    BFA_FCS_RETRY_TIMEOUT);
1410a36c61f9SKrishna Gudipati 		} else {
1411a36c61f9SKrishna Gudipati 			/*
1412a36c61f9SKrishna Gudipati 			 * set state to offline
1413a36c61f9SKrishna Gudipati 			 */
1414a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1415a36c61f9SKrishna Gudipati 		}
1416a36c61f9SKrishna Gudipati 		break;
1417a36c61f9SKrishna Gudipati 
1418a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_OK:
1419a36c61f9SKrishna Gudipati 		/*
1420a36c61f9SKrishna Gudipati 		 * Initiate Register Port Attributes
1421a36c61f9SKrishna Gudipati 		 */
1422a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1423a36c61f9SKrishna Gudipati 		fdmi->retry_cnt = 0;
1424a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1425a36c61f9SKrishna Gudipati 		break;
1426a36c61f9SKrishna Gudipati 
1427a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1428a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(fdmi->fcxp);
1429a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1430a36c61f9SKrishna Gudipati 		break;
1431a36c61f9SKrishna Gudipati 
1432a36c61f9SKrishna Gudipati 	default:
1433a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1434a36c61f9SKrishna Gudipati 	}
1435a36c61f9SKrishna Gudipati }
1436a36c61f9SKrishna Gudipati 
1437a36c61f9SKrishna Gudipati static void
1438a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1439a36c61f9SKrishna Gudipati 				enum port_fdmi_event event)
1440a36c61f9SKrishna Gudipati {
1441a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1442a36c61f9SKrishna Gudipati 
1443a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1444a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1445a36c61f9SKrishna Gudipati 
1446a36c61f9SKrishna Gudipati 	switch (event) {
1447a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_TIMEOUT:
1448a36c61f9SKrishna Gudipati 		/*
1449a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
1450a36c61f9SKrishna Gudipati 		 */
1451a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba);
1452a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1453a36c61f9SKrishna Gudipati 		break;
1454a36c61f9SKrishna Gudipati 
1455a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1456a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1457a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fdmi->timer);
1458a36c61f9SKrishna Gudipati 		break;
1459a36c61f9SKrishna Gudipati 
1460a36c61f9SKrishna Gudipati 	default:
1461a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1462a36c61f9SKrishna Gudipati 	}
1463a36c61f9SKrishna Gudipati }
1464a36c61f9SKrishna Gudipati 
1465a36c61f9SKrishna Gudipati /*
1466a36c61f9SKrishna Gudipati * RPRT : Register Port
1467a36c61f9SKrishna Gudipati  */
1468a36c61f9SKrishna Gudipati static void
1469a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1470a36c61f9SKrishna Gudipati 				  enum port_fdmi_event event)
1471a36c61f9SKrishna Gudipati {
1472a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1473a36c61f9SKrishna Gudipati 
1474a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1475a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1476a36c61f9SKrishna Gudipati 
1477a36c61f9SKrishna Gudipati 	switch (event) {
1478a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RPRT_SENT:
1479a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt);
1480a36c61f9SKrishna Gudipati 		break;
1481a36c61f9SKrishna Gudipati 
1482a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1483a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1484a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1485a36c61f9SKrishna Gudipati 					   &fdmi->fcxp_wqe);
1486a36c61f9SKrishna Gudipati 		break;
1487a36c61f9SKrishna Gudipati 
1488a36c61f9SKrishna Gudipati 	default:
1489a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1490a36c61f9SKrishna Gudipati 	}
1491a36c61f9SKrishna Gudipati }
1492a36c61f9SKrishna Gudipati 
1493a36c61f9SKrishna Gudipati static void
1494a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1495a36c61f9SKrishna Gudipati 			enum port_fdmi_event event)
1496a36c61f9SKrishna Gudipati {
1497a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1498a36c61f9SKrishna Gudipati 
1499a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1500a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1501a36c61f9SKrishna Gudipati 
1502a36c61f9SKrishna Gudipati 	switch (event) {
1503a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_ERROR:
1504a36c61f9SKrishna Gudipati 		/*
1505a36c61f9SKrishna Gudipati 		 * if max retries have not been reached, start timer for a
1506a36c61f9SKrishna Gudipati 		 * delayed retry
1507a36c61f9SKrishna Gudipati 		 */
1508a36c61f9SKrishna Gudipati 		if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1509a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1510a36c61f9SKrishna Gudipati 					bfa_fcs_lport_fdmi_sm_rprt_retry);
1511a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1512a36c61f9SKrishna Gudipati 					    &fdmi->timer,
1513a36c61f9SKrishna Gudipati 					    bfa_fcs_lport_fdmi_timeout, fdmi,
1514a36c61f9SKrishna Gudipati 					    BFA_FCS_RETRY_TIMEOUT);
15157725ccfdSJing Huang 
15167725ccfdSJing Huang 		} else {
1517a36c61f9SKrishna Gudipati 			/*
1518a36c61f9SKrishna Gudipati 			 * set state to offline
1519a36c61f9SKrishna Gudipati 			 */
1520a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1521a36c61f9SKrishna Gudipati 			fdmi->retry_cnt = 0;
15227725ccfdSJing Huang 		}
1523a36c61f9SKrishna Gudipati 		break;
1524a36c61f9SKrishna Gudipati 
1525a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_OK:
1526a36c61f9SKrishna Gudipati 		fdmi->retry_cnt = 0;
1527a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1528a36c61f9SKrishna Gudipati 		break;
1529a36c61f9SKrishna Gudipati 
1530a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1531a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(fdmi->fcxp);
1532a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1533a36c61f9SKrishna Gudipati 		break;
1534a36c61f9SKrishna Gudipati 
1535a36c61f9SKrishna Gudipati 	default:
1536a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1537a36c61f9SKrishna Gudipati 	}
1538a36c61f9SKrishna Gudipati }
1539a36c61f9SKrishna Gudipati 
1540a36c61f9SKrishna Gudipati static void
1541a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1542a36c61f9SKrishna Gudipati 				enum port_fdmi_event event)
1543a36c61f9SKrishna Gudipati {
1544a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1545a36c61f9SKrishna Gudipati 
1546a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1547a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1548a36c61f9SKrishna Gudipati 
1549a36c61f9SKrishna Gudipati 	switch (event) {
1550a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_TIMEOUT:
1551a36c61f9SKrishna Gudipati 		/*
1552a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
1553a36c61f9SKrishna Gudipati 		 */
1554a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt);
1555a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1556a36c61f9SKrishna Gudipati 		break;
1557a36c61f9SKrishna Gudipati 
1558a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1559a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1560a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fdmi->timer);
1561a36c61f9SKrishna Gudipati 		break;
1562a36c61f9SKrishna Gudipati 
1563a36c61f9SKrishna Gudipati 	default:
1564a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1565a36c61f9SKrishna Gudipati 	}
1566a36c61f9SKrishna Gudipati }
1567a36c61f9SKrishna Gudipati 
1568a36c61f9SKrishna Gudipati /*
1569a36c61f9SKrishna Gudipati  * Register Port Attributes
1570a36c61f9SKrishna Gudipati  */
1571a36c61f9SKrishna Gudipati static void
1572a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1573a36c61f9SKrishna Gudipati 				 enum port_fdmi_event event)
1574a36c61f9SKrishna Gudipati {
1575a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1576a36c61f9SKrishna Gudipati 
1577a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1578a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1579a36c61f9SKrishna Gudipati 
1580a36c61f9SKrishna Gudipati 	switch (event) {
1581a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RPA_SENT:
1582a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa);
1583a36c61f9SKrishna Gudipati 		break;
1584a36c61f9SKrishna Gudipati 
1585a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1586a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1587a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1588a36c61f9SKrishna Gudipati 					   &fdmi->fcxp_wqe);
1589a36c61f9SKrishna Gudipati 		break;
1590a36c61f9SKrishna Gudipati 
1591a36c61f9SKrishna Gudipati 	default:
1592a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1593a36c61f9SKrishna Gudipati 	}
1594a36c61f9SKrishna Gudipati }
1595a36c61f9SKrishna Gudipati 
1596a36c61f9SKrishna Gudipati static void
1597a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1598a36c61f9SKrishna Gudipati 			enum port_fdmi_event event)
1599a36c61f9SKrishna Gudipati {
1600a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1601a36c61f9SKrishna Gudipati 
1602a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1603a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1604a36c61f9SKrishna Gudipati 
1605a36c61f9SKrishna Gudipati 	switch (event) {
1606a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_ERROR:
1607a36c61f9SKrishna Gudipati 		/*
1608a36c61f9SKrishna Gudipati 		 * if max retries have not been reached, start timer for a
1609a36c61f9SKrishna Gudipati 		 * delayed retry
1610a36c61f9SKrishna Gudipati 		 */
1611a36c61f9SKrishna Gudipati 		if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1612a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry);
1613a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1614a36c61f9SKrishna Gudipati 					    &fdmi->timer,
1615a36c61f9SKrishna Gudipati 					    bfa_fcs_lport_fdmi_timeout, fdmi,
1616a36c61f9SKrishna Gudipati 					    BFA_FCS_RETRY_TIMEOUT);
1617a36c61f9SKrishna Gudipati 		} else {
1618a36c61f9SKrishna Gudipati 			/*
1619a36c61f9SKrishna Gudipati 			 * set state to offline
1620a36c61f9SKrishna Gudipati 			 */
1621a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1622a36c61f9SKrishna Gudipati 			fdmi->retry_cnt = 0;
1623a36c61f9SKrishna Gudipati 		}
1624a36c61f9SKrishna Gudipati 		break;
1625a36c61f9SKrishna Gudipati 
1626a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_OK:
1627a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1628a36c61f9SKrishna Gudipati 		fdmi->retry_cnt = 0;
1629a36c61f9SKrishna Gudipati 		break;
1630a36c61f9SKrishna Gudipati 
1631a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1632a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(fdmi->fcxp);
1633a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1634a36c61f9SKrishna Gudipati 		break;
1635a36c61f9SKrishna Gudipati 
1636a36c61f9SKrishna Gudipati 	default:
1637a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1638a36c61f9SKrishna Gudipati 	}
1639a36c61f9SKrishna Gudipati }
1640a36c61f9SKrishna Gudipati 
1641a36c61f9SKrishna Gudipati static void
1642a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1643a36c61f9SKrishna Gudipati 			       enum port_fdmi_event event)
1644a36c61f9SKrishna Gudipati {
1645a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1646a36c61f9SKrishna Gudipati 
1647a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1648a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1649a36c61f9SKrishna Gudipati 
1650a36c61f9SKrishna Gudipati 	switch (event) {
1651a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_TIMEOUT:
1652a36c61f9SKrishna Gudipati 		/*
1653a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
1654a36c61f9SKrishna Gudipati 		 */
1655a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1656a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1657a36c61f9SKrishna Gudipati 		break;
1658a36c61f9SKrishna Gudipati 
1659a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1660a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1661a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fdmi->timer);
1662a36c61f9SKrishna Gudipati 		break;
1663a36c61f9SKrishna Gudipati 
1664a36c61f9SKrishna Gudipati 	default:
1665a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1666a36c61f9SKrishna Gudipati 	}
1667a36c61f9SKrishna Gudipati }
1668a36c61f9SKrishna Gudipati 
1669a36c61f9SKrishna Gudipati static void
1670a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1671a36c61f9SKrishna Gudipati 				enum port_fdmi_event event)
1672a36c61f9SKrishna Gudipati {
1673a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1674a36c61f9SKrishna Gudipati 
1675a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1676a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1677a36c61f9SKrishna Gudipati 
1678a36c61f9SKrishna Gudipati 	switch (event) {
1679a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1680a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1681a36c61f9SKrishna Gudipati 		break;
1682a36c61f9SKrishna Gudipati 
1683a36c61f9SKrishna Gudipati 	default:
1684a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1685a36c61f9SKrishna Gudipati 	}
1686a36c61f9SKrishna Gudipati }
16875fbe25c7SJing Huang /*
1688a36c61f9SKrishna Gudipati  *  FDMI is disabled state.
1689a36c61f9SKrishna Gudipati  */
1690a36c61f9SKrishna Gudipati static void
1691a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi,
1692a36c61f9SKrishna Gudipati 			     enum port_fdmi_event event)
1693a36c61f9SKrishna Gudipati {
1694a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1695a36c61f9SKrishna Gudipati 
1696a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1697a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1698a36c61f9SKrishna Gudipati 
1699a36c61f9SKrishna Gudipati 	/* No op State. It can only be enabled at Driver Init. */
1700a36c61f9SKrishna Gudipati }
1701a36c61f9SKrishna Gudipati 
17025fbe25c7SJing Huang /*
1703a36c61f9SKrishna Gudipati *  RHBA : Register HBA Attributes.
1704a36c61f9SKrishna Gudipati  */
1705a36c61f9SKrishna Gudipati static void
1706a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1707a36c61f9SKrishna Gudipati {
1708a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1709a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1710a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
1711a36c61f9SKrishna Gudipati 	int             len, attr_len;
1712a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1713a36c61f9SKrishna Gudipati 	u8        *pyld;
1714a36c61f9SKrishna Gudipati 
1715a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1716a36c61f9SKrishna Gudipati 
1717c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1718c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1719a36c61f9SKrishna Gudipati 	if (!fcxp) {
1720a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1721c3f1b123SKrishna Gudipati 				bfa_fcs_lport_fdmi_send_rhba, fdmi, BFA_TRUE);
1722a36c61f9SKrishna Gudipati 		return;
1723a36c61f9SKrishna Gudipati 	}
1724a36c61f9SKrishna Gudipati 	fdmi->fcxp = fcxp;
1725a36c61f9SKrishna Gudipati 
1726a36c61f9SKrishna Gudipati 	pyld = bfa_fcxp_get_reqbuf(fcxp);
17276a18b167SJing Huang 	memset(pyld, 0, FC_MAX_PDUSZ);
1728a36c61f9SKrishna Gudipati 
1729a36c61f9SKrishna Gudipati 	len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
1730a36c61f9SKrishna Gudipati 				   FDMI_RHBA);
1731a36c61f9SKrishna Gudipati 
1732a36c61f9SKrishna Gudipati 	attr_len =
1733a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi,
1734a36c61f9SKrishna Gudipati 					  (u8 *) ((struct ct_hdr_s *) pyld
1735a36c61f9SKrishna Gudipati 						       + 1));
1736a36c61f9SKrishna Gudipati 
1737a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1738a36c61f9SKrishna Gudipati 			  FC_CLASS_3, (len + attr_len), &fchs,
1739a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi,
1740a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
1741a36c61f9SKrishna Gudipati 
1742a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
1743a36c61f9SKrishna Gudipati }
1744a36c61f9SKrishna Gudipati 
1745a36c61f9SKrishna Gudipati static          u16
1746a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
1747a36c61f9SKrishna Gudipati {
1748a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1749a36c61f9SKrishna Gudipati 	struct bfa_fcs_fdmi_hba_attr_s hba_attr;
1750a36c61f9SKrishna Gudipati 	struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr;
1751a36c61f9SKrishna Gudipati 	struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld;
1752a36c61f9SKrishna Gudipati 	struct fdmi_attr_s *attr;
1753a36c61f9SKrishna Gudipati 	u8        *curr_ptr;
1754a36c61f9SKrishna Gudipati 	u16        len, count;
175550444a34SMaggie 	u16	templen;
1756a36c61f9SKrishna Gudipati 
1757a36c61f9SKrishna Gudipati 	/*
1758a36c61f9SKrishna Gudipati 	 * get hba attributes
1759a36c61f9SKrishna Gudipati 	 */
1760a36c61f9SKrishna Gudipati 	bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
1761a36c61f9SKrishna Gudipati 
1762a36c61f9SKrishna Gudipati 	rhba->hba_id = bfa_fcs_lport_get_pwwn(port);
1763ba816ea8SJing Huang 	rhba->port_list.num_ports = cpu_to_be32(1);
1764a36c61f9SKrishna Gudipati 	rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port);
1765a36c61f9SKrishna Gudipati 
1766a36c61f9SKrishna Gudipati 	len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
1767a36c61f9SKrishna Gudipati 
1768a36c61f9SKrishna Gudipati 	count = 0;
1769a36c61f9SKrishna Gudipati 	len += sizeof(rhba->hba_attr_blk.attr_count);
1770a36c61f9SKrishna Gudipati 
1771a36c61f9SKrishna Gudipati 	/*
1772a36c61f9SKrishna Gudipati 	 * fill out the invididual entries of the HBA attrib Block
1773a36c61f9SKrishna Gudipati 	 */
1774a36c61f9SKrishna Gudipati 	curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
1775a36c61f9SKrishna Gudipati 
1776a36c61f9SKrishna Gudipati 	/*
1777a36c61f9SKrishna Gudipati 	 * Node Name
1778a36c61f9SKrishna Gudipati 	 */
1779a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1780ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME);
178150444a34SMaggie 	templen = sizeof(wwn_t);
178250444a34SMaggie 	memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen);
178350444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
178450444a34SMaggie 	len += templen;
1785a36c61f9SKrishna Gudipati 	count++;
178650444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
178750444a34SMaggie 			     sizeof(templen));
1788a36c61f9SKrishna Gudipati 
1789a36c61f9SKrishna Gudipati 	/*
1790a36c61f9SKrishna Gudipati 	 * Manufacturer
1791a36c61f9SKrishna Gudipati 	 */
1792a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1793ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER);
179450444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->manufacturer);
179550444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->manufacturer, templen);
179650444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
179750444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
179850444a34SMaggie 	len += templen;
1799a36c61f9SKrishna Gudipati 	count++;
180050444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
180150444a34SMaggie 			     sizeof(templen));
1802a36c61f9SKrishna Gudipati 
1803a36c61f9SKrishna Gudipati 	/*
1804a36c61f9SKrishna Gudipati 	 * Serial Number
1805a36c61f9SKrishna Gudipati 	 */
1806a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1807ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM);
180850444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->serial_num);
180950444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->serial_num, templen);
181050444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
181150444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
181250444a34SMaggie 	len += templen;
1813a36c61f9SKrishna Gudipati 	count++;
181450444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
181550444a34SMaggie 			     sizeof(templen));
1816a36c61f9SKrishna Gudipati 
1817a36c61f9SKrishna Gudipati 	/*
1818a36c61f9SKrishna Gudipati 	 * Model
1819a36c61f9SKrishna Gudipati 	 */
1820a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1821ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL);
182250444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->model);
182350444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->model, templen);
182450444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
182550444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
182650444a34SMaggie 	len += templen;
1827a36c61f9SKrishna Gudipati 	count++;
182850444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
182950444a34SMaggie 			     sizeof(templen));
1830a36c61f9SKrishna Gudipati 
1831a36c61f9SKrishna Gudipati 	/*
1832a36c61f9SKrishna Gudipati 	 * Model Desc
1833a36c61f9SKrishna Gudipati 	 */
1834a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1835ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC);
183650444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->model_desc);
183750444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->model_desc, templen);
183850444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
183950444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
184050444a34SMaggie 	len += templen;
1841a36c61f9SKrishna Gudipati 	count++;
184250444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
184350444a34SMaggie 			     sizeof(templen));
1844a36c61f9SKrishna Gudipati 
1845a36c61f9SKrishna Gudipati 	/*
1846a36c61f9SKrishna Gudipati 	 * H/W Version
1847a36c61f9SKrishna Gudipati 	 */
1848a36c61f9SKrishna Gudipati 	if (fcs_hba_attr->hw_version[0] != '\0') {
1849a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
1850ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION);
185150444a34SMaggie 		templen = (u16) strlen(fcs_hba_attr->hw_version);
185250444a34SMaggie 		memcpy(attr->value, fcs_hba_attr->hw_version, templen);
185350444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
185450444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
185550444a34SMaggie 		len += templen;
1856a36c61f9SKrishna Gudipati 		count++;
185750444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
185850444a34SMaggie 					 sizeof(templen));
1859a36c61f9SKrishna Gudipati 	}
1860a36c61f9SKrishna Gudipati 
1861a36c61f9SKrishna Gudipati 	/*
1862a36c61f9SKrishna Gudipati 	 * Driver Version
1863a36c61f9SKrishna Gudipati 	 */
1864a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1865ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION);
186650444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->driver_version);
186750444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->driver_version, templen);
186850444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
186950444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1870dd5aaf45SKrishna Gudipati 	len += templen;
1871a36c61f9SKrishna Gudipati 	count++;
187250444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
187350444a34SMaggie 			     sizeof(templen));
1874a36c61f9SKrishna Gudipati 
1875a36c61f9SKrishna Gudipati 	/*
1876a36c61f9SKrishna Gudipati 	 * Option Rom Version
1877a36c61f9SKrishna Gudipati 	 */
1878a36c61f9SKrishna Gudipati 	if (fcs_hba_attr->option_rom_ver[0] != '\0') {
1879a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
1880ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION);
188150444a34SMaggie 		templen = (u16) strlen(fcs_hba_attr->option_rom_ver);
188250444a34SMaggie 		memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen);
188350444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
188450444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
188550444a34SMaggie 		len += templen;
1886a36c61f9SKrishna Gudipati 		count++;
188750444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
188850444a34SMaggie 					 sizeof(templen));
1889a36c61f9SKrishna Gudipati 	}
1890a36c61f9SKrishna Gudipati 
1891a36c61f9SKrishna Gudipati 	/*
1892a36c61f9SKrishna Gudipati 	 * f/w Version = driver version
1893a36c61f9SKrishna Gudipati 	 */
1894a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1895ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION);
189650444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->driver_version);
189750444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->driver_version, templen);
189850444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
189950444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
190050444a34SMaggie 	len += templen;
1901a36c61f9SKrishna Gudipati 	count++;
190250444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
190350444a34SMaggie 			     sizeof(templen));
1904a36c61f9SKrishna Gudipati 
1905a36c61f9SKrishna Gudipati 	/*
1906a36c61f9SKrishna Gudipati 	 * OS Name
1907a36c61f9SKrishna Gudipati 	 */
1908a36c61f9SKrishna Gudipati 	if (fcs_hba_attr->os_name[0] != '\0') {
1909a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
1910ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME);
191150444a34SMaggie 		templen = (u16) strlen(fcs_hba_attr->os_name);
191250444a34SMaggie 		memcpy(attr->value, fcs_hba_attr->os_name, templen);
191350444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
191450444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
191550444a34SMaggie 		len += templen;
1916a36c61f9SKrishna Gudipati 		count++;
191750444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
191850444a34SMaggie 					sizeof(templen));
1919a36c61f9SKrishna Gudipati 	}
1920a36c61f9SKrishna Gudipati 
1921a36c61f9SKrishna Gudipati 	/*
1922a36c61f9SKrishna Gudipati 	 * MAX_CT_PAYLOAD
1923a36c61f9SKrishna Gudipati 	 */
1924a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1925ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT);
192650444a34SMaggie 	templen = sizeof(fcs_hba_attr->max_ct_pyld);
192750444a34SMaggie 	memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen);
192850444a34SMaggie 	len += templen;
1929a36c61f9SKrishna Gudipati 	count++;
193050444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
193150444a34SMaggie 			     sizeof(templen));
1932a36c61f9SKrishna Gudipati 
1933a36c61f9SKrishna Gudipati 	/*
1934a36c61f9SKrishna Gudipati 	 * Update size of payload
1935a36c61f9SKrishna Gudipati 	 */
19365fbe25c7SJing Huang 	len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
1937a36c61f9SKrishna Gudipati 
1938ba816ea8SJing Huang 	rhba->hba_attr_blk.attr_count = cpu_to_be32(count);
1939a36c61f9SKrishna Gudipati 	return len;
1940a36c61f9SKrishna Gudipati }
1941a36c61f9SKrishna Gudipati 
1942a36c61f9SKrishna Gudipati static void
1943a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
1944a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
1945a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
1946a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
1947a36c61f9SKrishna Gudipati {
1948a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi =
1949a36c61f9SKrishna Gudipati 				(struct bfa_fcs_lport_fdmi_s *) cbarg;
1950a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1951a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
1952a36c61f9SKrishna Gudipati 
1953a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1954a36c61f9SKrishna Gudipati 
1955a36c61f9SKrishna Gudipati 	/*
1956a36c61f9SKrishna Gudipati 	 * Sanity Checks
1957a36c61f9SKrishna Gudipati 	 */
1958a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
1959a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
1960a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1961a36c61f9SKrishna Gudipati 		return;
1962a36c61f9SKrishna Gudipati 	}
1963a36c61f9SKrishna Gudipati 
1964a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1965ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1966a36c61f9SKrishna Gudipati 
1967a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1968a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
1969a36c61f9SKrishna Gudipati 		return;
1970a36c61f9SKrishna Gudipati 	}
1971a36c61f9SKrishna Gudipati 
1972a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
1973a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
1974a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1975a36c61f9SKrishna Gudipati }
1976a36c61f9SKrishna Gudipati 
19775fbe25c7SJing Huang /*
1978a36c61f9SKrishna Gudipati *  RPRT : Register Port
1979a36c61f9SKrishna Gudipati  */
1980a36c61f9SKrishna Gudipati static void
1981a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1982a36c61f9SKrishna Gudipati {
1983a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1984a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1985a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
1986a36c61f9SKrishna Gudipati 	u16        len, attr_len;
1987a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1988a36c61f9SKrishna Gudipati 	u8        *pyld;
1989a36c61f9SKrishna Gudipati 
1990a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1991a36c61f9SKrishna Gudipati 
1992c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1993c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1994a36c61f9SKrishna Gudipati 	if (!fcxp) {
1995a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1996c3f1b123SKrishna Gudipati 				bfa_fcs_lport_fdmi_send_rprt, fdmi, BFA_TRUE);
1997a36c61f9SKrishna Gudipati 		return;
1998a36c61f9SKrishna Gudipati 	}
1999a36c61f9SKrishna Gudipati 	fdmi->fcxp = fcxp;
2000a36c61f9SKrishna Gudipati 
2001a36c61f9SKrishna Gudipati 	pyld = bfa_fcxp_get_reqbuf(fcxp);
20026a18b167SJing Huang 	memset(pyld, 0, FC_MAX_PDUSZ);
2003a36c61f9SKrishna Gudipati 
2004a36c61f9SKrishna Gudipati 	len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2005a36c61f9SKrishna Gudipati 				   FDMI_RPRT);
2006a36c61f9SKrishna Gudipati 
2007a36c61f9SKrishna Gudipati 	attr_len =
2008a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi,
2009a36c61f9SKrishna Gudipati 					  (u8 *) ((struct ct_hdr_s *) pyld
2010a36c61f9SKrishna Gudipati 						       + 1));
2011a36c61f9SKrishna Gudipati 
2012a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2013a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len + attr_len, &fchs,
2014a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi,
2015a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
2016a36c61f9SKrishna Gudipati 
2017a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
2018a36c61f9SKrishna Gudipati }
2019a36c61f9SKrishna Gudipati 
20205fbe25c7SJing Huang /*
2021a36c61f9SKrishna Gudipati  * This routine builds Port Attribute Block that used in RPA, RPRT commands.
2022a36c61f9SKrishna Gudipati  */
2023a36c61f9SKrishna Gudipati static          u16
2024a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
2025a36c61f9SKrishna Gudipati 				       u8 *pyld)
2026a36c61f9SKrishna Gudipati {
2027a36c61f9SKrishna Gudipati 	struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
2028a36c61f9SKrishna Gudipati 	struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld;
2029a36c61f9SKrishna Gudipati 	struct fdmi_attr_s *attr;
2030a36c61f9SKrishna Gudipati 	u8        *curr_ptr;
2031a36c61f9SKrishna Gudipati 	u16        len;
2032a36c61f9SKrishna Gudipati 	u8	count = 0;
203350444a34SMaggie 	u16	templen;
2034a36c61f9SKrishna Gudipati 
2035a36c61f9SKrishna Gudipati 	/*
2036a36c61f9SKrishna Gudipati 	 * get port attributes
2037a36c61f9SKrishna Gudipati 	 */
2038a36c61f9SKrishna Gudipati 	bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
2039a36c61f9SKrishna Gudipati 
2040a36c61f9SKrishna Gudipati 	len = sizeof(port_attrib->attr_count);
2041a36c61f9SKrishna Gudipati 
2042a36c61f9SKrishna Gudipati 	/*
2043a36c61f9SKrishna Gudipati 	 * fill out the invididual entries
2044a36c61f9SKrishna Gudipati 	 */
2045a36c61f9SKrishna Gudipati 	curr_ptr = (u8 *) &port_attrib->port_attr;
2046a36c61f9SKrishna Gudipati 
2047a36c61f9SKrishna Gudipati 	/*
2048a36c61f9SKrishna Gudipati 	 * FC4 Types
2049a36c61f9SKrishna Gudipati 	 */
2050a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2051ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES);
205250444a34SMaggie 	templen = sizeof(fcs_port_attr.supp_fc4_types);
205350444a34SMaggie 	memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen);
205450444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
205550444a34SMaggie 	len += templen;
2056a36c61f9SKrishna Gudipati 	++count;
2057a36c61f9SKrishna Gudipati 	attr->len =
205850444a34SMaggie 		cpu_to_be16(templen + sizeof(attr->type) +
205950444a34SMaggie 			     sizeof(templen));
2060a36c61f9SKrishna Gudipati 
2061a36c61f9SKrishna Gudipati 	/*
2062a36c61f9SKrishna Gudipati 	 * Supported Speed
2063a36c61f9SKrishna Gudipati 	 */
2064a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2065ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED);
206650444a34SMaggie 	templen = sizeof(fcs_port_attr.supp_speed);
206750444a34SMaggie 	memcpy(attr->value, &fcs_port_attr.supp_speed, templen);
206850444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
206950444a34SMaggie 	len += templen;
2070a36c61f9SKrishna Gudipati 	++count;
2071a36c61f9SKrishna Gudipati 	attr->len =
207250444a34SMaggie 		cpu_to_be16(templen + sizeof(attr->type) +
207350444a34SMaggie 			     sizeof(templen));
2074a36c61f9SKrishna Gudipati 
2075a36c61f9SKrishna Gudipati 	/*
2076a36c61f9SKrishna Gudipati 	 * current Port Speed
2077a36c61f9SKrishna Gudipati 	 */
2078a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2079ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED);
208050444a34SMaggie 	templen = sizeof(fcs_port_attr.curr_speed);
208150444a34SMaggie 	memcpy(attr->value, &fcs_port_attr.curr_speed, templen);
208250444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
208350444a34SMaggie 	len += templen;
2084a36c61f9SKrishna Gudipati 	++count;
208550444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
208650444a34SMaggie 			     sizeof(templen));
2087a36c61f9SKrishna Gudipati 
2088a36c61f9SKrishna Gudipati 	/*
2089a36c61f9SKrishna Gudipati 	 * max frame size
2090a36c61f9SKrishna Gudipati 	 */
2091a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2092ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE);
209350444a34SMaggie 	templen = sizeof(fcs_port_attr.max_frm_size);
209450444a34SMaggie 	memcpy(attr->value, &fcs_port_attr.max_frm_size, templen);
209550444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
209650444a34SMaggie 	len += templen;
2097a36c61f9SKrishna Gudipati 	++count;
209850444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
209950444a34SMaggie 			     sizeof(templen));
2100a36c61f9SKrishna Gudipati 
2101a36c61f9SKrishna Gudipati 	/*
2102a36c61f9SKrishna Gudipati 	 * OS Device Name
2103a36c61f9SKrishna Gudipati 	 */
2104a36c61f9SKrishna Gudipati 	if (fcs_port_attr.os_device_name[0] != '\0') {
2105a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
2106ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME);
210750444a34SMaggie 		templen = (u16) strlen(fcs_port_attr.os_device_name);
210850444a34SMaggie 		memcpy(attr->value, fcs_port_attr.os_device_name, templen);
210950444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
211050444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
211150444a34SMaggie 		len += templen;
2112a36c61f9SKrishna Gudipati 		++count;
211350444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
211450444a34SMaggie 					sizeof(templen));
2115a36c61f9SKrishna Gudipati 	}
2116a36c61f9SKrishna Gudipati 	/*
2117a36c61f9SKrishna Gudipati 	 * Host Name
2118a36c61f9SKrishna Gudipati 	 */
2119a36c61f9SKrishna Gudipati 	if (fcs_port_attr.host_name[0] != '\0') {
2120a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
2121ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME);
212250444a34SMaggie 		templen = (u16) strlen(fcs_port_attr.host_name);
212350444a34SMaggie 		memcpy(attr->value, fcs_port_attr.host_name, templen);
212450444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
212550444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
212650444a34SMaggie 		len += templen;
2127a36c61f9SKrishna Gudipati 		++count;
212850444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
212950444a34SMaggie 				sizeof(templen));
2130a36c61f9SKrishna Gudipati 	}
2131a36c61f9SKrishna Gudipati 
2132a36c61f9SKrishna Gudipati 	/*
2133a36c61f9SKrishna Gudipati 	 * Update size of payload
2134a36c61f9SKrishna Gudipati 	 */
2135ba816ea8SJing Huang 	port_attrib->attr_count = cpu_to_be32(count);
21365fbe25c7SJing Huang 	len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
2137a36c61f9SKrishna Gudipati 	return len;
2138a36c61f9SKrishna Gudipati }
2139a36c61f9SKrishna Gudipati 
2140a36c61f9SKrishna Gudipati static          u16
2141a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2142a36c61f9SKrishna Gudipati {
2143a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2144a36c61f9SKrishna Gudipati 	struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld;
2145a36c61f9SKrishna Gudipati 	u16        len;
2146a36c61f9SKrishna Gudipati 
2147a36c61f9SKrishna Gudipati 	rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs));
2148a36c61f9SKrishna Gudipati 	rprt->port_name = bfa_fcs_lport_get_pwwn(port);
2149a36c61f9SKrishna Gudipati 
2150a36c61f9SKrishna Gudipati 	len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2151a36c61f9SKrishna Gudipati 				(u8 *) &rprt->port_attr_blk);
2152a36c61f9SKrishna Gudipati 
2153a36c61f9SKrishna Gudipati 	len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
2154a36c61f9SKrishna Gudipati 
2155a36c61f9SKrishna Gudipati 	return len;
2156a36c61f9SKrishna Gudipati }
2157a36c61f9SKrishna Gudipati 
2158a36c61f9SKrishna Gudipati static void
2159a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2160a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
2161a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
2162a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
2163a36c61f9SKrishna Gudipati {
2164a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi =
2165a36c61f9SKrishna Gudipati 			(struct bfa_fcs_lport_fdmi_s *) cbarg;
2166a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2167a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
2168a36c61f9SKrishna Gudipati 
2169a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2170a36c61f9SKrishna Gudipati 
2171a36c61f9SKrishna Gudipati 	/*
2172a36c61f9SKrishna Gudipati 	 * Sanity Checks
2173a36c61f9SKrishna Gudipati 	 */
2174a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2175a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
2176a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2177a36c61f9SKrishna Gudipati 		return;
2178a36c61f9SKrishna Gudipati 	}
2179a36c61f9SKrishna Gudipati 
2180a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2181ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2182a36c61f9SKrishna Gudipati 
2183a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2184a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2185a36c61f9SKrishna Gudipati 		return;
2186a36c61f9SKrishna Gudipati 	}
2187a36c61f9SKrishna Gudipati 
2188a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
2189a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
2190a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2191a36c61f9SKrishna Gudipati }
2192a36c61f9SKrishna Gudipati 
21935fbe25c7SJing Huang /*
2194a36c61f9SKrishna Gudipati *  RPA : Register Port Attributes.
2195a36c61f9SKrishna Gudipati  */
2196a36c61f9SKrishna Gudipati static void
2197a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2198a36c61f9SKrishna Gudipati {
2199a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
2200a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2201a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
2202a36c61f9SKrishna Gudipati 	u16        len, attr_len;
2203a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2204a36c61f9SKrishna Gudipati 	u8        *pyld;
2205a36c61f9SKrishna Gudipati 
2206a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2207a36c61f9SKrishna Gudipati 
2208c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
2209c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2210a36c61f9SKrishna Gudipati 	if (!fcxp) {
2211a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2212c3f1b123SKrishna Gudipati 				bfa_fcs_lport_fdmi_send_rpa, fdmi, BFA_TRUE);
2213a36c61f9SKrishna Gudipati 		return;
2214a36c61f9SKrishna Gudipati 	}
2215a36c61f9SKrishna Gudipati 	fdmi->fcxp = fcxp;
2216a36c61f9SKrishna Gudipati 
2217a36c61f9SKrishna Gudipati 	pyld = bfa_fcxp_get_reqbuf(fcxp);
22186a18b167SJing Huang 	memset(pyld, 0, FC_MAX_PDUSZ);
2219a36c61f9SKrishna Gudipati 
2220a36c61f9SKrishna Gudipati 	len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2221a36c61f9SKrishna Gudipati 				   FDMI_RPA);
2222a36c61f9SKrishna Gudipati 
22235fbe25c7SJing Huang 	attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi,
22245fbe25c7SJing Huang 				(u8 *) ((struct ct_hdr_s *) pyld + 1));
2225a36c61f9SKrishna Gudipati 
2226a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2227a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len + attr_len, &fchs,
2228a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi,
2229a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
2230a36c61f9SKrishna Gudipati 
2231a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
2232a36c61f9SKrishna Gudipati }
2233a36c61f9SKrishna Gudipati 
2234a36c61f9SKrishna Gudipati static          u16
2235a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2236a36c61f9SKrishna Gudipati {
2237a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2238a36c61f9SKrishna Gudipati 	struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld;
2239a36c61f9SKrishna Gudipati 	u16        len;
2240a36c61f9SKrishna Gudipati 
2241a36c61f9SKrishna Gudipati 	rpa->port_name = bfa_fcs_lport_get_pwwn(port);
2242a36c61f9SKrishna Gudipati 
2243a36c61f9SKrishna Gudipati 	len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2244a36c61f9SKrishna Gudipati 				(u8 *) &rpa->port_attr_blk);
2245a36c61f9SKrishna Gudipati 
2246a36c61f9SKrishna Gudipati 	len += sizeof(rpa->port_name);
2247a36c61f9SKrishna Gudipati 
2248a36c61f9SKrishna Gudipati 	return len;
2249a36c61f9SKrishna Gudipati }
2250a36c61f9SKrishna Gudipati 
2251a36c61f9SKrishna Gudipati static void
2252a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2253a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
2254a36c61f9SKrishna Gudipati 			u32 resid_len, struct fchs_s *rsp_fchs)
2255a36c61f9SKrishna Gudipati {
2256a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi =
2257a36c61f9SKrishna Gudipati 				(struct bfa_fcs_lport_fdmi_s *) cbarg;
2258a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2259a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
2260a36c61f9SKrishna Gudipati 
2261a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2262a36c61f9SKrishna Gudipati 
2263a36c61f9SKrishna Gudipati 	/*
2264a36c61f9SKrishna Gudipati 	 * Sanity Checks
2265a36c61f9SKrishna Gudipati 	 */
2266a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2267a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
2268a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2269a36c61f9SKrishna Gudipati 		return;
2270a36c61f9SKrishna Gudipati 	}
2271a36c61f9SKrishna Gudipati 
2272a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2273ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2274a36c61f9SKrishna Gudipati 
2275a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2276a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2277a36c61f9SKrishna Gudipati 		return;
2278a36c61f9SKrishna Gudipati 	}
2279a36c61f9SKrishna Gudipati 
2280a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
2281a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
2282a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2283a36c61f9SKrishna Gudipati }
2284a36c61f9SKrishna Gudipati 
2285a36c61f9SKrishna Gudipati static void
2286a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout(void *arg)
2287a36c61f9SKrishna Gudipati {
2288a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg;
2289a36c61f9SKrishna Gudipati 
2290a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
2291a36c61f9SKrishna Gudipati }
2292a36c61f9SKrishna Gudipati 
229352f94b6fSMaggie static void
2294a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2295a36c61f9SKrishna Gudipati 			 struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
2296a36c61f9SKrishna Gudipati {
2297a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2298a36c61f9SKrishna Gudipati 	struct bfa_fcs_driver_info_s  *driver_info = &port->fcs->driver_info;
2299a36c61f9SKrishna Gudipati 
23006a18b167SJing Huang 	memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
2301a36c61f9SKrishna Gudipati 
2302a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
2303a36c61f9SKrishna Gudipati 					hba_attr->manufacturer);
2304a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
2305a36c61f9SKrishna Gudipati 					hba_attr->serial_num);
2306a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2307a36c61f9SKrishna Gudipati 					hba_attr->model);
2308a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2309a36c61f9SKrishna Gudipati 					hba_attr->model_desc);
2310a36c61f9SKrishna Gudipati 	bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc,
2311a36c61f9SKrishna Gudipati 					hba_attr->hw_version);
2312a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
2313a36c61f9SKrishna Gudipati 					hba_attr->option_rom_ver);
2314a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc,
2315a36c61f9SKrishna Gudipati 					hba_attr->fw_version);
2316a36c61f9SKrishna Gudipati 
2317a36c61f9SKrishna Gudipati 	strncpy(hba_attr->driver_version, (char *)driver_info->version,
2318a36c61f9SKrishna Gudipati 		sizeof(hba_attr->driver_version));
2319a36c61f9SKrishna Gudipati 
2320a36c61f9SKrishna Gudipati 	strncpy(hba_attr->os_name, driver_info->host_os_name,
2321a36c61f9SKrishna Gudipati 		sizeof(hba_attr->os_name));
2322a36c61f9SKrishna Gudipati 
2323a36c61f9SKrishna Gudipati 	/*
2324a36c61f9SKrishna Gudipati 	 * If there is a patch level, append it
2325a36c61f9SKrishna Gudipati 	 * to the os name along with a separator
2326a36c61f9SKrishna Gudipati 	 */
2327a36c61f9SKrishna Gudipati 	if (driver_info->host_os_patch[0] != '\0') {
2328a36c61f9SKrishna Gudipati 		strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
2329a36c61f9SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
2330a36c61f9SKrishna Gudipati 		strncat(hba_attr->os_name, driver_info->host_os_patch,
2331a36c61f9SKrishna Gudipati 				sizeof(driver_info->host_os_patch));
2332a36c61f9SKrishna Gudipati 	}
2333a36c61f9SKrishna Gudipati 
2334ba816ea8SJing Huang 	hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ);
2335a36c61f9SKrishna Gudipati }
2336a36c61f9SKrishna Gudipati 
233752f94b6fSMaggie static void
2338a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2339a36c61f9SKrishna Gudipati 			  struct bfa_fcs_fdmi_port_attr_s *port_attr)
2340a36c61f9SKrishna Gudipati {
2341a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2342a36c61f9SKrishna Gudipati 	struct bfa_fcs_driver_info_s  *driver_info = &port->fcs->driver_info;
2343a36c61f9SKrishna Gudipati 	struct bfa_port_attr_s pport_attr;
2344a36c61f9SKrishna Gudipati 
23456a18b167SJing Huang 	memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
2346a36c61f9SKrishna Gudipati 
2347a36c61f9SKrishna Gudipati 	/*
2348a36c61f9SKrishna Gudipati 	 * get pport attributes from hal
2349a36c61f9SKrishna Gudipati 	 */
2350a36c61f9SKrishna Gudipati 	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2351a36c61f9SKrishna Gudipati 
2352a36c61f9SKrishna Gudipati 	/*
2353a36c61f9SKrishna Gudipati 	 * get FC4 type Bitmask
2354a36c61f9SKrishna Gudipati 	 */
2355a36c61f9SKrishna Gudipati 	fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
2356a36c61f9SKrishna Gudipati 
2357a36c61f9SKrishna Gudipati 	/*
2358a36c61f9SKrishna Gudipati 	 * Supported Speeds
2359a36c61f9SKrishna Gudipati 	 */
2360d7be54ccSKrishna Gudipati 	switch (pport_attr.speed_supported) {
2361d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_16GBPS:
2362d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2363d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G);
2364d7be54ccSKrishna Gudipati 		break;
2365d7be54ccSKrishna Gudipati 
2366d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_10GBPS:
2367d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2368d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G);
2369d7be54ccSKrishna Gudipati 		break;
2370d7be54ccSKrishna Gudipati 
2371d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_8GBPS:
2372d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2373d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G);
2374d7be54ccSKrishna Gudipati 		break;
2375d7be54ccSKrishna Gudipati 
2376d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_4GBPS:
2377d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2378d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G);
2379d7be54ccSKrishna Gudipati 		break;
2380d7be54ccSKrishna Gudipati 
2381d7be54ccSKrishna Gudipati 	default:
2382d7be54ccSKrishna Gudipati 		bfa_sm_fault(port->fcs, pport_attr.speed_supported);
2383d7be54ccSKrishna Gudipati 	}
2384a36c61f9SKrishna Gudipati 
2385a36c61f9SKrishna Gudipati 	/*
2386a36c61f9SKrishna Gudipati 	 * Current Speed
2387a36c61f9SKrishna Gudipati 	 */
2388d7be54ccSKrishna Gudipati 	port_attr->curr_speed = cpu_to_be32(
2389d7be54ccSKrishna Gudipati 				bfa_fcs_fdmi_convert_speed(pport_attr.speed));
2390a36c61f9SKrishna Gudipati 
2391a36c61f9SKrishna Gudipati 	/*
2392a36c61f9SKrishna Gudipati 	 * Max PDU Size.
2393a36c61f9SKrishna Gudipati 	 */
2394ba816ea8SJing Huang 	port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ);
2395a36c61f9SKrishna Gudipati 
2396a36c61f9SKrishna Gudipati 	/*
2397a36c61f9SKrishna Gudipati 	 * OS device Name
2398a36c61f9SKrishna Gudipati 	 */
2399a36c61f9SKrishna Gudipati 	strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
2400a36c61f9SKrishna Gudipati 		sizeof(port_attr->os_device_name));
2401a36c61f9SKrishna Gudipati 
2402a36c61f9SKrishna Gudipati 	/*
2403a36c61f9SKrishna Gudipati 	 * Host name
2404a36c61f9SKrishna Gudipati 	 */
2405a36c61f9SKrishna Gudipati 	strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
2406a36c61f9SKrishna Gudipati 		sizeof(port_attr->host_name));
24077725ccfdSJing Huang 
24087725ccfdSJing Huang }
24097725ccfdSJing Huang 
2410d7be54ccSKrishna Gudipati /*
2411d7be54ccSKrishna Gudipati  * Convert BFA speed to FDMI format.
2412d7be54ccSKrishna Gudipati  */
2413d7be54ccSKrishna Gudipati u32
2414d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed)
2415d7be54ccSKrishna Gudipati {
2416d7be54ccSKrishna Gudipati 	u32	ret;
2417d7be54ccSKrishna Gudipati 
2418d7be54ccSKrishna Gudipati 	switch (pport_speed) {
2419d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_1GBPS:
2420d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_2GBPS:
2421d7be54ccSKrishna Gudipati 		ret = pport_speed;
2422d7be54ccSKrishna Gudipati 		break;
2423d7be54ccSKrishna Gudipati 
2424d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_4GBPS:
2425d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_4G;
2426d7be54ccSKrishna Gudipati 		break;
2427d7be54ccSKrishna Gudipati 
2428d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_8GBPS:
2429d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_8G;
2430d7be54ccSKrishna Gudipati 		break;
2431d7be54ccSKrishna Gudipati 
2432d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_10GBPS:
2433d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_10G;
2434d7be54ccSKrishna Gudipati 		break;
2435d7be54ccSKrishna Gudipati 
2436d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_16GBPS:
2437d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_16G;
2438d7be54ccSKrishna Gudipati 		break;
2439d7be54ccSKrishna Gudipati 
2440d7be54ccSKrishna Gudipati 	default:
2441d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_UNKNOWN;
2442d7be54ccSKrishna Gudipati 	}
2443d7be54ccSKrishna Gudipati 	return ret;
2444d7be54ccSKrishna Gudipati }
24457725ccfdSJing Huang 
2446a36c61f9SKrishna Gudipati void
2447a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms)
2448a36c61f9SKrishna Gudipati {
2449a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2450a36c61f9SKrishna Gudipati 
2451a36c61f9SKrishna Gudipati 	fdmi->ms = ms;
2452a36c61f9SKrishna Gudipati 	if (ms->port->fcs->fdmi_enabled)
2453a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
2454a36c61f9SKrishna Gudipati 	else
2455a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled);
2456a36c61f9SKrishna Gudipati }
2457a36c61f9SKrishna Gudipati 
2458a36c61f9SKrishna Gudipati void
2459a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms)
2460a36c61f9SKrishna Gudipati {
2461a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2462a36c61f9SKrishna Gudipati 
2463a36c61f9SKrishna Gudipati 	fdmi->ms = ms;
2464a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
2465a36c61f9SKrishna Gudipati }
2466a36c61f9SKrishna Gudipati 
2467a36c61f9SKrishna Gudipati void
2468a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms)
2469a36c61f9SKrishna Gudipati {
2470a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2471a36c61f9SKrishna Gudipati 
2472a36c61f9SKrishna Gudipati 	fdmi->ms = ms;
2473a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
2474a36c61f9SKrishna Gudipati }
2475a36c61f9SKrishna Gudipati 
2476a36c61f9SKrishna Gudipati #define BFA_FCS_MS_CMD_MAX_RETRIES  2
2477a36c61f9SKrishna Gudipati 
2478a36c61f9SKrishna Gudipati /*
2479a36c61f9SKrishna Gudipati  * forward declarations
2480a36c61f9SKrishna Gudipati  */
2481a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_send_plogi(void *ms_cbarg,
2482a36c61f9SKrishna Gudipati 					   struct bfa_fcxp_s *fcxp_alloced);
2483a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_timeout(void *arg);
2484a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_plogi_response(void *fcsarg,
2485a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
2486a36c61f9SKrishna Gudipati 					       void *cbarg,
2487a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
2488a36c61f9SKrishna Gudipati 					       u32 rsp_len,
2489a36c61f9SKrishna Gudipati 					       u32 resid_len,
2490a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
2491a36c61f9SKrishna Gudipati 
2492a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_ms_send_gmal(void *ms_cbarg,
2493a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
2494a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_gmal_response(void *fcsarg,
2495a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
2496a36c61f9SKrishna Gudipati 					       void *cbarg,
2497a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
2498a36c61f9SKrishna Gudipati 					       u32 rsp_len,
2499a36c61f9SKrishna Gudipati 					       u32 resid_len,
2500a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
2501a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_ms_send_gfn(void *ms_cbarg,
2502a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
2503a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_gfn_response(void *fcsarg,
2504a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
2505a36c61f9SKrishna Gudipati 					       void *cbarg,
2506a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
2507a36c61f9SKrishna Gudipati 					       u32 rsp_len,
2508a36c61f9SKrishna Gudipati 					       u32 resid_len,
2509a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
25105fbe25c7SJing Huang /*
2511a36c61f9SKrishna Gudipati  *  fcs_ms_sm FCS MS state machine
2512a36c61f9SKrishna Gudipati  */
2513a36c61f9SKrishna Gudipati 
25145fbe25c7SJing Huang /*
2515a36c61f9SKrishna Gudipati  *  MS State Machine events
2516a36c61f9SKrishna Gudipati  */
2517a36c61f9SKrishna Gudipati enum port_ms_event {
2518a36c61f9SKrishna Gudipati 	MSSM_EVENT_PORT_ONLINE = 1,
2519a36c61f9SKrishna Gudipati 	MSSM_EVENT_PORT_OFFLINE = 2,
2520a36c61f9SKrishna Gudipati 	MSSM_EVENT_RSP_OK = 3,
2521a36c61f9SKrishna Gudipati 	MSSM_EVENT_RSP_ERROR = 4,
2522a36c61f9SKrishna Gudipati 	MSSM_EVENT_TIMEOUT = 5,
2523a36c61f9SKrishna Gudipati 	MSSM_EVENT_FCXP_SENT = 6,
2524a36c61f9SKrishna Gudipati 	MSSM_EVENT_PORT_FABRIC_RSCN = 7
2525a36c61f9SKrishna Gudipati };
2526a36c61f9SKrishna Gudipati 
2527a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2528a36c61f9SKrishna Gudipati 					   enum port_ms_event event);
2529a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2530a36c61f9SKrishna Gudipati 						 enum port_ms_event event);
2531a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2532a36c61f9SKrishna Gudipati 					 enum port_ms_event event);
2533a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2534a36c61f9SKrishna Gudipati 					       enum port_ms_event event);
2535a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2536a36c61f9SKrishna Gudipati 						 enum port_ms_event event);
2537a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2538a36c61f9SKrishna Gudipati 					 enum port_ms_event event);
2539a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2540a36c61f9SKrishna Gudipati 					       enum port_ms_event event);
2541a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
2542a36c61f9SKrishna Gudipati 						 enum port_ms_event event);
2543a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2544a36c61f9SKrishna Gudipati 					 enum port_ms_event event);
2545a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2546a36c61f9SKrishna Gudipati 					       enum port_ms_event event);
2547a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2548a36c61f9SKrishna Gudipati 					  enum port_ms_event event);
25495fbe25c7SJing Huang /*
2550a36c61f9SKrishna Gudipati  *	Start in offline state - awaiting NS to send start.
2551a36c61f9SKrishna Gudipati  */
2552a36c61f9SKrishna Gudipati static void
2553a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2554a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2555a36c61f9SKrishna Gudipati {
2556a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2557a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2558a36c61f9SKrishna Gudipati 
2559a36c61f9SKrishna Gudipati 	switch (event) {
2560a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_ONLINE:
2561a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2562a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_plogi(ms, NULL);
2563a36c61f9SKrishna Gudipati 		break;
2564a36c61f9SKrishna Gudipati 
2565a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2566a36c61f9SKrishna Gudipati 		break;
2567a36c61f9SKrishna Gudipati 
2568a36c61f9SKrishna Gudipati 	default:
2569a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2570a36c61f9SKrishna Gudipati 	}
2571a36c61f9SKrishna Gudipati }
2572a36c61f9SKrishna Gudipati 
2573a36c61f9SKrishna Gudipati static void
2574a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2575a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2576a36c61f9SKrishna Gudipati {
2577a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2578a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2579a36c61f9SKrishna Gudipati 
2580a36c61f9SKrishna Gudipati 	switch (event) {
2581a36c61f9SKrishna Gudipati 	case MSSM_EVENT_FCXP_SENT:
2582a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi);
2583a36c61f9SKrishna Gudipati 		break;
2584a36c61f9SKrishna Gudipati 
2585a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2586a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2587a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2588a36c61f9SKrishna Gudipati 					   &ms->fcxp_wqe);
2589a36c61f9SKrishna Gudipati 		break;
2590a36c61f9SKrishna Gudipati 
2591a36c61f9SKrishna Gudipati 	default:
2592a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2593a36c61f9SKrishna Gudipati 	}
2594a36c61f9SKrishna Gudipati }
2595a36c61f9SKrishna Gudipati 
2596a36c61f9SKrishna Gudipati static void
2597a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2598a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2599a36c61f9SKrishna Gudipati {
2600a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2601a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2602a36c61f9SKrishna Gudipati 
2603a36c61f9SKrishna Gudipati 	switch (event) {
2604a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_ERROR:
2605a36c61f9SKrishna Gudipati 		/*
2606a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
2607a36c61f9SKrishna Gudipati 		 */
2608a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry);
2609a36c61f9SKrishna Gudipati 		ms->port->stats.ms_retries++;
2610a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2611a36c61f9SKrishna Gudipati 				    &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2612a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
2613a36c61f9SKrishna Gudipati 		break;
2614a36c61f9SKrishna Gudipati 
2615a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_OK:
2616a36c61f9SKrishna Gudipati 		/*
2617a36c61f9SKrishna Gudipati 		 * since plogi is done, now invoke MS related sub-modules
2618a36c61f9SKrishna Gudipati 		 */
2619a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_online(ms);
2620a36c61f9SKrishna Gudipati 
26215fbe25c7SJing Huang 		/*
2622a36c61f9SKrishna Gudipati 		 * if this is a Vport, go to online state.
2623a36c61f9SKrishna Gudipati 		 */
2624a36c61f9SKrishna Gudipati 		if (ms->port->vport) {
2625a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2626a36c61f9SKrishna Gudipati 			break;
2627a36c61f9SKrishna Gudipati 		}
2628a36c61f9SKrishna Gudipati 
2629a36c61f9SKrishna Gudipati 		/*
2630a36c61f9SKrishna Gudipati 		 * For a base port we need to get the
2631a36c61f9SKrishna Gudipati 		 * switch's IP address.
2632a36c61f9SKrishna Gudipati 		 */
2633a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2634a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gmal(ms, NULL);
2635a36c61f9SKrishna Gudipati 		break;
2636a36c61f9SKrishna Gudipati 
2637a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2638a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2639a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ms->fcxp);
2640a36c61f9SKrishna Gudipati 		break;
2641a36c61f9SKrishna Gudipati 
2642a36c61f9SKrishna Gudipati 	default:
2643a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2644a36c61f9SKrishna Gudipati 	}
2645a36c61f9SKrishna Gudipati }
2646a36c61f9SKrishna Gudipati 
2647a36c61f9SKrishna Gudipati static void
2648a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2649a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2650a36c61f9SKrishna Gudipati {
2651a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2652a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2653a36c61f9SKrishna Gudipati 
2654a36c61f9SKrishna Gudipati 	switch (event) {
2655a36c61f9SKrishna Gudipati 	case MSSM_EVENT_TIMEOUT:
2656a36c61f9SKrishna Gudipati 		/*
2657a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
2658a36c61f9SKrishna Gudipati 		 */
2659a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2660a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_plogi(ms, NULL);
2661a36c61f9SKrishna Gudipati 		break;
2662a36c61f9SKrishna Gudipati 
2663a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2664a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2665a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ms->timer);
2666a36c61f9SKrishna Gudipati 		break;
2667a36c61f9SKrishna Gudipati 
2668a36c61f9SKrishna Gudipati 	default:
2669a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2670a36c61f9SKrishna Gudipati 	}
2671a36c61f9SKrishna Gudipati }
2672a36c61f9SKrishna Gudipati 
2673a36c61f9SKrishna Gudipati static void
2674a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2675a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2676a36c61f9SKrishna Gudipati {
2677a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2678a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2679a36c61f9SKrishna Gudipati 
2680a36c61f9SKrishna Gudipati 	switch (event) {
2681a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2682a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2683a36c61f9SKrishna Gudipati 		break;
2684a36c61f9SKrishna Gudipati 
2685a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_FABRIC_RSCN:
2686a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2687a36c61f9SKrishna Gudipati 		ms->retry_cnt = 0;
2688a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gfn(ms, NULL);
2689a36c61f9SKrishna Gudipati 		break;
2690a36c61f9SKrishna Gudipati 
2691a36c61f9SKrishna Gudipati 	default:
2692a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2693a36c61f9SKrishna Gudipati 	}
2694a36c61f9SKrishna Gudipati }
2695a36c61f9SKrishna Gudipati 
2696a36c61f9SKrishna Gudipati static void
2697a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2698a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2699a36c61f9SKrishna Gudipati {
2700a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2701a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2702a36c61f9SKrishna Gudipati 
2703a36c61f9SKrishna Gudipati 	switch (event) {
2704a36c61f9SKrishna Gudipati 	case MSSM_EVENT_FCXP_SENT:
2705a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal);
2706a36c61f9SKrishna Gudipati 		break;
2707a36c61f9SKrishna Gudipati 
2708a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2709a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2710a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2711a36c61f9SKrishna Gudipati 					   &ms->fcxp_wqe);
2712a36c61f9SKrishna Gudipati 		break;
2713a36c61f9SKrishna Gudipati 
2714a36c61f9SKrishna Gudipati 	default:
2715a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2716a36c61f9SKrishna Gudipati 	}
2717a36c61f9SKrishna Gudipati }
2718a36c61f9SKrishna Gudipati 
2719a36c61f9SKrishna Gudipati static void
2720a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2721a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2722a36c61f9SKrishna Gudipati {
2723a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2724a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2725a36c61f9SKrishna Gudipati 
2726a36c61f9SKrishna Gudipati 	switch (event) {
2727a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_ERROR:
2728a36c61f9SKrishna Gudipati 		/*
2729a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
2730a36c61f9SKrishna Gudipati 		 */
2731a36c61f9SKrishna Gudipati 		if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
2732a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry);
2733a36c61f9SKrishna Gudipati 			ms->port->stats.ms_retries++;
2734a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2735a36c61f9SKrishna Gudipati 				&ms->timer, bfa_fcs_lport_ms_timeout, ms,
2736a36c61f9SKrishna Gudipati 				BFA_FCS_RETRY_TIMEOUT);
2737a36c61f9SKrishna Gudipati 		} else {
2738a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2739a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ms_send_gfn(ms, NULL);
2740a36c61f9SKrishna Gudipati 			ms->retry_cnt = 0;
2741a36c61f9SKrishna Gudipati 		}
2742a36c61f9SKrishna Gudipati 		break;
2743a36c61f9SKrishna Gudipati 
2744a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_OK:
2745a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2746a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gfn(ms, NULL);
2747a36c61f9SKrishna Gudipati 		break;
2748a36c61f9SKrishna Gudipati 
2749a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2750a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2751a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ms->fcxp);
2752a36c61f9SKrishna Gudipati 		break;
2753a36c61f9SKrishna Gudipati 
2754a36c61f9SKrishna Gudipati 	default:
2755a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2756a36c61f9SKrishna Gudipati 	}
2757a36c61f9SKrishna Gudipati }
2758a36c61f9SKrishna Gudipati 
2759a36c61f9SKrishna Gudipati static void
2760a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2761a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2762a36c61f9SKrishna Gudipati {
2763a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2764a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2765a36c61f9SKrishna Gudipati 
2766a36c61f9SKrishna Gudipati 	switch (event) {
2767a36c61f9SKrishna Gudipati 	case MSSM_EVENT_TIMEOUT:
2768a36c61f9SKrishna Gudipati 		/*
2769a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
2770a36c61f9SKrishna Gudipati 		 */
2771a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2772a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gmal(ms, NULL);
2773a36c61f9SKrishna Gudipati 		break;
2774a36c61f9SKrishna Gudipati 
2775a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2776a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2777a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ms->timer);
2778a36c61f9SKrishna Gudipati 		break;
2779a36c61f9SKrishna Gudipati 
2780a36c61f9SKrishna Gudipati 	default:
2781a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2782a36c61f9SKrishna Gudipati 	}
2783a36c61f9SKrishna Gudipati }
27845fbe25c7SJing Huang /*
2785a36c61f9SKrishna Gudipati  *  ms_pvt MS local functions
2786a36c61f9SKrishna Gudipati  */
2787a36c61f9SKrishna Gudipati 
2788a36c61f9SKrishna Gudipati static void
2789a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2790a36c61f9SKrishna Gudipati {
2791a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2792a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
2793a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2794a36c61f9SKrishna Gudipati 	int		len;
2795a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2796a36c61f9SKrishna Gudipati 
2797a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
2798a36c61f9SKrishna Gudipati 
2799c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
2800c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2801a36c61f9SKrishna Gudipati 	if (!fcxp) {
2802a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2803c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ms_send_gmal, ms, BFA_TRUE);
2804a36c61f9SKrishna Gudipati 		return;
2805a36c61f9SKrishna Gudipati 	}
2806a36c61f9SKrishna Gudipati 	ms->fcxp = fcxp;
2807a36c61f9SKrishna Gudipati 
2808a36c61f9SKrishna Gudipati 	len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2809a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port),
2810f7f73812SMaggie Zhang 				 port->fabric->lps->pr_nwwn);
2811a36c61f9SKrishna Gudipati 
2812a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2813a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
2814a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ms_gmal_response, (void *)ms,
2815a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
2816a36c61f9SKrishna Gudipati 
2817a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
2818a36c61f9SKrishna Gudipati }
2819a36c61f9SKrishna Gudipati 
2820a36c61f9SKrishna Gudipati static void
2821a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2822a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
2823a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
2824a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
2825a36c61f9SKrishna Gudipati {
2826a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
2827a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
2828a36c61f9SKrishna Gudipati 	struct ct_hdr_s		*cthdr = NULL;
2829a36c61f9SKrishna Gudipati 	struct fcgs_gmal_resp_s *gmal_resp;
2830a36c61f9SKrishna Gudipati 	struct fcgs_gmal_entry_s *gmal_entry;
2831a36c61f9SKrishna Gudipati 	u32		num_entries;
2832a36c61f9SKrishna Gudipati 	u8			*rsp_str;
2833a36c61f9SKrishna Gudipati 
2834a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
2835a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2836a36c61f9SKrishna Gudipati 
2837a36c61f9SKrishna Gudipati 	/*
2838a36c61f9SKrishna Gudipati 	 * Sanity Checks
2839a36c61f9SKrishna Gudipati 	 */
2840a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2841a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
2842a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2843a36c61f9SKrishna Gudipati 		return;
2844a36c61f9SKrishna Gudipati 	}
2845a36c61f9SKrishna Gudipati 
2846a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2847ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2848a36c61f9SKrishna Gudipati 
2849a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2850a36c61f9SKrishna Gudipati 		gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
2851a36c61f9SKrishna Gudipati 
2852ba816ea8SJing Huang 		num_entries = be32_to_cpu(gmal_resp->ms_len);
2853a36c61f9SKrishna Gudipati 		if (num_entries == 0) {
2854a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2855a36c61f9SKrishna Gudipati 			return;
2856a36c61f9SKrishna Gudipati 		}
2857a36c61f9SKrishna Gudipati 		/*
2858a36c61f9SKrishna Gudipati 		* The response could contain multiple Entries.
2859a36c61f9SKrishna Gudipati 		* Entries for SNMP interface, etc.
2860a36c61f9SKrishna Gudipati 		* We look for the entry with a telnet prefix.
2861a36c61f9SKrishna Gudipati 		* First "http://" entry refers to IP addr
2862a36c61f9SKrishna Gudipati 		*/
2863a36c61f9SKrishna Gudipati 
2864a36c61f9SKrishna Gudipati 		gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma;
2865a36c61f9SKrishna Gudipati 		while (num_entries > 0) {
2866a36c61f9SKrishna Gudipati 			if (strncmp(gmal_entry->prefix,
2867a36c61f9SKrishna Gudipati 				CT_GMAL_RESP_PREFIX_HTTP,
2868a36c61f9SKrishna Gudipati 				sizeof(gmal_entry->prefix)) == 0) {
2869a36c61f9SKrishna Gudipati 
2870a36c61f9SKrishna Gudipati 				/*
2871a36c61f9SKrishna Gudipati 				* if the IP address is terminating with a '/',
2872a36c61f9SKrishna Gudipati 				* remove it.
2873a36c61f9SKrishna Gudipati 				* Byte 0 consists of the length of the string.
2874a36c61f9SKrishna Gudipati 				*/
2875a36c61f9SKrishna Gudipati 				rsp_str = &(gmal_entry->prefix[0]);
2876a36c61f9SKrishna Gudipati 				if (rsp_str[gmal_entry->len-1] == '/')
2877a36c61f9SKrishna Gudipati 					rsp_str[gmal_entry->len-1] = 0;
2878a36c61f9SKrishna Gudipati 
2879a36c61f9SKrishna Gudipati 				/* copy IP Address to fabric */
2880a36c61f9SKrishna Gudipati 				strncpy(bfa_fcs_lport_get_fabric_ipaddr(port),
2881a36c61f9SKrishna Gudipati 					gmal_entry->ip_addr,
2882a36c61f9SKrishna Gudipati 					BFA_FCS_FABRIC_IPADDR_SZ);
2883a36c61f9SKrishna Gudipati 				break;
2884a36c61f9SKrishna Gudipati 			} else {
2885a36c61f9SKrishna Gudipati 				--num_entries;
2886a36c61f9SKrishna Gudipati 				++gmal_entry;
2887a36c61f9SKrishna Gudipati 			}
2888a36c61f9SKrishna Gudipati 		}
2889a36c61f9SKrishna Gudipati 
2890a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
2891a36c61f9SKrishna Gudipati 		return;
2892a36c61f9SKrishna Gudipati 	}
2893a36c61f9SKrishna Gudipati 
2894a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
2895a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
2896a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
2897a36c61f9SKrishna Gudipati }
2898a36c61f9SKrishna Gudipati 
2899a36c61f9SKrishna Gudipati static void
2900a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_sending(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_FCXP_SENT:
2908a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn);
2909a36c61f9SKrishna Gudipati 		break;
2910a36c61f9SKrishna Gudipati 
2911a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2912a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2913a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2914a36c61f9SKrishna Gudipati 					   &ms->fcxp_wqe);
2915a36c61f9SKrishna Gudipati 		break;
2916a36c61f9SKrishna Gudipati 
2917a36c61f9SKrishna Gudipati 	default:
2918a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2919a36c61f9SKrishna Gudipati 	}
2920a36c61f9SKrishna Gudipati }
2921a36c61f9SKrishna Gudipati 
2922a36c61f9SKrishna Gudipati static void
2923a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2924a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2925a36c61f9SKrishna Gudipati {
2926a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2927a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2928a36c61f9SKrishna Gudipati 
2929a36c61f9SKrishna Gudipati 	switch (event) {
2930a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_ERROR:
2931a36c61f9SKrishna Gudipati 		/*
2932a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
2933a36c61f9SKrishna Gudipati 		 */
2934a36c61f9SKrishna Gudipati 		if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
2935a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry);
2936a36c61f9SKrishna Gudipati 			ms->port->stats.ms_retries++;
2937a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2938a36c61f9SKrishna Gudipati 				&ms->timer, bfa_fcs_lport_ms_timeout, ms,
2939a36c61f9SKrishna Gudipati 				BFA_FCS_RETRY_TIMEOUT);
2940a36c61f9SKrishna Gudipati 		} else {
2941a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2942a36c61f9SKrishna Gudipati 			ms->retry_cnt = 0;
2943a36c61f9SKrishna Gudipati 		}
2944a36c61f9SKrishna Gudipati 		break;
2945a36c61f9SKrishna Gudipati 
2946a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_OK:
2947a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2948a36c61f9SKrishna Gudipati 		break;
2949a36c61f9SKrishna Gudipati 
2950a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2951a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2952a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ms->fcxp);
2953a36c61f9SKrishna Gudipati 		break;
2954a36c61f9SKrishna Gudipati 
2955a36c61f9SKrishna Gudipati 	default:
2956a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2957a36c61f9SKrishna Gudipati 	}
2958a36c61f9SKrishna Gudipati }
2959a36c61f9SKrishna Gudipati 
2960a36c61f9SKrishna Gudipati static void
2961a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2962a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2963a36c61f9SKrishna Gudipati {
2964a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2965a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2966a36c61f9SKrishna Gudipati 
2967a36c61f9SKrishna Gudipati 	switch (event) {
2968a36c61f9SKrishna Gudipati 	case MSSM_EVENT_TIMEOUT:
2969a36c61f9SKrishna Gudipati 		/*
2970a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
2971a36c61f9SKrishna Gudipati 		 */
2972a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2973a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gfn(ms, NULL);
2974a36c61f9SKrishna Gudipati 		break;
2975a36c61f9SKrishna Gudipati 
2976a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2977a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2978a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ms->timer);
2979a36c61f9SKrishna Gudipati 		break;
2980a36c61f9SKrishna Gudipati 
2981a36c61f9SKrishna Gudipati 	default:
2982a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2983a36c61f9SKrishna Gudipati 	}
2984a36c61f9SKrishna Gudipati }
29855fbe25c7SJing Huang /*
2986a36c61f9SKrishna Gudipati  *  ms_pvt MS local functions
2987a36c61f9SKrishna Gudipati  */
2988a36c61f9SKrishna Gudipati 
2989a36c61f9SKrishna Gudipati static void
2990a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2991a36c61f9SKrishna Gudipati {
2992a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2993a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
2994a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
2995a36c61f9SKrishna Gudipati 	int			len;
2996a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2997a36c61f9SKrishna Gudipati 
2998a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
2999a36c61f9SKrishna Gudipati 
3000c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
3001c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3002a36c61f9SKrishna Gudipati 	if (!fcxp) {
3003a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3004c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ms_send_gfn, ms, BFA_TRUE);
3005a36c61f9SKrishna Gudipati 		return;
3006a36c61f9SKrishna Gudipati 	}
3007a36c61f9SKrishna Gudipati 	ms->fcxp = fcxp;
3008a36c61f9SKrishna Gudipati 
3009a36c61f9SKrishna Gudipati 	len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3010a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port),
3011f7f73812SMaggie Zhang 				 port->fabric->lps->pr_nwwn);
3012a36c61f9SKrishna Gudipati 
3013a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3014a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3015a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ms_gfn_response, (void *)ms,
3016a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
3017a36c61f9SKrishna Gudipati 
3018a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
3019a36c61f9SKrishna Gudipati }
3020a36c61f9SKrishna Gudipati 
3021a36c61f9SKrishna Gudipati static void
3022a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3023a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
3024a36c61f9SKrishna Gudipati 			u32 resid_len, struct fchs_s *rsp_fchs)
3025a36c61f9SKrishna Gudipati {
3026a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3027a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
3028a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr = NULL;
3029a36c61f9SKrishna Gudipati 	wwn_t	       *gfn_resp;
3030a36c61f9SKrishna Gudipati 
3031a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
3032a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3033a36c61f9SKrishna Gudipati 
3034a36c61f9SKrishna Gudipati 	/*
3035a36c61f9SKrishna Gudipati 	 * Sanity Checks
3036a36c61f9SKrishna Gudipati 	 */
3037a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3038a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
3039a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3040a36c61f9SKrishna Gudipati 		return;
3041a36c61f9SKrishna Gudipati 	}
3042a36c61f9SKrishna Gudipati 
3043a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3044ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3045a36c61f9SKrishna Gudipati 
3046a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3047a36c61f9SKrishna Gudipati 		gfn_resp = (wwn_t *)(cthdr + 1);
3048a36c61f9SKrishna Gudipati 		/* check if it has actually changed */
3049a36c61f9SKrishna Gudipati 		if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port),
3050a36c61f9SKrishna Gudipati 				gfn_resp, sizeof(wwn_t)) != 0)) {
3051a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
3052a36c61f9SKrishna Gudipati 		}
3053a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
3054a36c61f9SKrishna Gudipati 		return;
3055a36c61f9SKrishna Gudipati 	}
3056a36c61f9SKrishna Gudipati 
3057a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
3058a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
3059a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3060a36c61f9SKrishna Gudipati }
3061a36c61f9SKrishna Gudipati 
30625fbe25c7SJing Huang /*
3063a36c61f9SKrishna Gudipati  *  ms_pvt MS local functions
3064a36c61f9SKrishna Gudipati  */
3065a36c61f9SKrishna Gudipati 
3066a36c61f9SKrishna Gudipati static void
3067a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3068a36c61f9SKrishna Gudipati {
3069a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
3070a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ms->port;
3071a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
3072a36c61f9SKrishna Gudipati 	int	len;
3073a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3074a36c61f9SKrishna Gudipati 
3075a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
3076a36c61f9SKrishna Gudipati 
3077c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
3078c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3079a36c61f9SKrishna Gudipati 	if (!fcxp) {
3080a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_alloc_wait++;
3081a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3082c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ms_send_plogi, ms, BFA_TRUE);
3083a36c61f9SKrishna Gudipati 		return;
3084a36c61f9SKrishna Gudipati 	}
3085a36c61f9SKrishna Gudipati 	ms->fcxp = fcxp;
3086a36c61f9SKrishna Gudipati 
3087a36c61f9SKrishna Gudipati 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3088f16a1750SMaggie Zhang 			     bfa_hton3b(FC_MGMT_SERVER),
3089a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port), 0,
3090a36c61f9SKrishna Gudipati 			     port->port_cfg.pwwn, port->port_cfg.nwwn,
3091be540a99SKrishna Gudipati 			     bfa_fcport_get_maxfrsize(port->fcs->bfa),
3092be540a99SKrishna Gudipati 			     bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
3093a36c61f9SKrishna Gudipati 
3094a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3095a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3096a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ms_plogi_response, (void *)ms,
3097a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_ELS_TOV);
3098a36c61f9SKrishna Gudipati 
3099a36c61f9SKrishna Gudipati 	port->stats.ms_plogi_sent++;
3100a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
3101a36c61f9SKrishna Gudipati }
3102a36c61f9SKrishna Gudipati 
3103a36c61f9SKrishna Gudipati static void
3104a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3105a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status,
3106a36c61f9SKrishna Gudipati 			u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs)
3107a36c61f9SKrishna Gudipati {
3108a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3109a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ms->port;
3110a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd;
3111a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
3112a36c61f9SKrishna Gudipati 
3113a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
3114a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3115a36c61f9SKrishna Gudipati 
3116a36c61f9SKrishna Gudipati 	/*
3117a36c61f9SKrishna Gudipati 	 * Sanity Checks
3118a36c61f9SKrishna Gudipati 	 */
3119a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3120a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_rsp_err++;
3121a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
3122a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3123a36c61f9SKrishna Gudipati 		return;
3124a36c61f9SKrishna Gudipati 	}
3125a36c61f9SKrishna Gudipati 
3126a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
3127a36c61f9SKrishna Gudipati 
3128a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
3129a36c61f9SKrishna Gudipati 
3130a36c61f9SKrishna Gudipati 	case FC_ELS_ACC:
3131a36c61f9SKrishna Gudipati 		if (rsp_len < sizeof(struct fc_logi_s)) {
3132a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rsp_len);
3133a36c61f9SKrishna Gudipati 			port->stats.ms_plogi_acc_err++;
3134a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3135a36c61f9SKrishna Gudipati 			break;
3136a36c61f9SKrishna Gudipati 		}
3137a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_accepts++;
3138a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
3139a36c61f9SKrishna Gudipati 		break;
3140a36c61f9SKrishna Gudipati 
3141a36c61f9SKrishna Gudipati 	case FC_ELS_LS_RJT:
3142a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3143a36c61f9SKrishna Gudipati 
3144a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code);
3145a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code_expl);
3146a36c61f9SKrishna Gudipati 
3147a36c61f9SKrishna Gudipati 		port->stats.ms_rejects++;
3148a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3149a36c61f9SKrishna Gudipati 		break;
3150a36c61f9SKrishna Gudipati 
3151a36c61f9SKrishna Gudipati 	default:
3152a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_unknown_rsp++;
3153a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, els_cmd->els_code);
3154a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3155a36c61f9SKrishna Gudipati 	}
3156a36c61f9SKrishna Gudipati }
3157a36c61f9SKrishna Gudipati 
3158a36c61f9SKrishna Gudipati static void
3159a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_timeout(void *arg)
3160a36c61f9SKrishna Gudipati {
3161a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg;
3162a36c61f9SKrishna Gudipati 
3163a36c61f9SKrishna Gudipati 	ms->port->stats.ms_timeouts++;
3164a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
3165a36c61f9SKrishna Gudipati }
3166a36c61f9SKrishna Gudipati 
3167a36c61f9SKrishna Gudipati 
3168a36c61f9SKrishna Gudipati void
3169a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port)
3170a36c61f9SKrishna Gudipati {
3171a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3172a36c61f9SKrishna Gudipati 
3173a36c61f9SKrishna Gudipati 	ms->port = port;
3174a36c61f9SKrishna Gudipati 	bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3175a36c61f9SKrishna Gudipati 
3176a36c61f9SKrishna Gudipati 	/*
3177a36c61f9SKrishna Gudipati 	 * Invoke init routines of sub modules.
3178a36c61f9SKrishna Gudipati 	 */
3179a36c61f9SKrishna Gudipati 	bfa_fcs_lport_fdmi_init(ms);
3180a36c61f9SKrishna Gudipati }
3181a36c61f9SKrishna Gudipati 
3182a36c61f9SKrishna Gudipati void
3183a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port)
3184a36c61f9SKrishna Gudipati {
3185a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3186a36c61f9SKrishna Gudipati 
3187a36c61f9SKrishna Gudipati 	ms->port = port;
3188a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
3189a36c61f9SKrishna Gudipati 	bfa_fcs_lport_fdmi_offline(ms);
3190a36c61f9SKrishna Gudipati }
3191a36c61f9SKrishna Gudipati 
3192a36c61f9SKrishna Gudipati void
3193a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port)
3194a36c61f9SKrishna Gudipati {
3195a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3196a36c61f9SKrishna Gudipati 
3197a36c61f9SKrishna Gudipati 	ms->port = port;
3198a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
3199a36c61f9SKrishna Gudipati }
3200a36c61f9SKrishna Gudipati void
3201a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port)
3202a36c61f9SKrishna Gudipati {
3203a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3204a36c61f9SKrishna Gudipati 
3205a36c61f9SKrishna Gudipati 	/* todo.  Handle this only  when in Online state */
3206a36c61f9SKrishna Gudipati 	if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online))
3207a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
3208a36c61f9SKrishna Gudipati }
3209a36c61f9SKrishna Gudipati 
32105fbe25c7SJing Huang /*
3211a36c61f9SKrishna Gudipati  * @page ns_sm_info VPORT NS State Machine
3212a36c61f9SKrishna Gudipati  *
3213a36c61f9SKrishna Gudipati  * @section ns_sm_interactions VPORT NS State Machine Interactions
3214a36c61f9SKrishna Gudipati  *
3215a36c61f9SKrishna Gudipati  * @section ns_sm VPORT NS State Machine
3216a36c61f9SKrishna Gudipati  * img ns_sm.jpg
3217a36c61f9SKrishna Gudipati  */
3218a36c61f9SKrishna Gudipati 
3219a36c61f9SKrishna Gudipati /*
3220a36c61f9SKrishna Gudipati  * forward declarations
3221a36c61f9SKrishna Gudipati  */
3222a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_plogi(void *ns_cbarg,
3223a36c61f9SKrishna Gudipati 					   struct bfa_fcxp_s *fcxp_alloced);
3224a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg,
3225a36c61f9SKrishna Gudipati 					     struct bfa_fcxp_s *fcxp_alloced);
3226a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg,
3227a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
3228a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg,
3229a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
3230a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg,
3231a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
3232a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_timeout(void *arg);
3233a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_plogi_response(void *fcsarg,
3234a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
3235a36c61f9SKrishna Gudipati 					       void *cbarg,
3236a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
3237a36c61f9SKrishna Gudipati 					       u32 rsp_len,
3238a36c61f9SKrishna Gudipati 					       u32 resid_len,
3239a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
3240a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_rspn_id_response(void *fcsarg,
3241a36c61f9SKrishna Gudipati 						 struct bfa_fcxp_s *fcxp,
3242a36c61f9SKrishna Gudipati 						 void *cbarg,
3243a36c61f9SKrishna Gudipati 						 bfa_status_t req_status,
3244a36c61f9SKrishna Gudipati 						 u32 rsp_len,
3245a36c61f9SKrishna Gudipati 						 u32 resid_len,
3246a36c61f9SKrishna Gudipati 						 struct fchs_s *rsp_fchs);
3247a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_rft_id_response(void *fcsarg,
3248a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3249a36c61f9SKrishna Gudipati 						void *cbarg,
3250a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
3251a36c61f9SKrishna Gudipati 						u32 rsp_len,
3252a36c61f9SKrishna Gudipati 						u32 resid_len,
3253a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3254a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_rff_id_response(void *fcsarg,
3255a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3256a36c61f9SKrishna Gudipati 						void *cbarg,
3257a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
3258a36c61f9SKrishna Gudipati 						u32 rsp_len,
3259a36c61f9SKrishna Gudipati 						u32 resid_len,
3260a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3261a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_gid_ft_response(void *fcsarg,
3262a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3263a36c61f9SKrishna Gudipati 						void *cbarg,
3264a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
3265a36c61f9SKrishna Gudipati 						u32 rsp_len,
3266a36c61f9SKrishna Gudipati 						u32 resid_len,
3267a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3268a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_process_gidft_pids(
3269a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_s *port,
3270a36c61f9SKrishna Gudipati 				u32 *pid_buf, u32 n_pids);
3271a36c61f9SKrishna Gudipati 
3272a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port);
32735fbe25c7SJing Huang /*
3274a36c61f9SKrishna Gudipati  *  fcs_ns_sm FCS nameserver interface state machine
3275a36c61f9SKrishna Gudipati  */
3276a36c61f9SKrishna Gudipati 
32775fbe25c7SJing Huang /*
3278a36c61f9SKrishna Gudipati  * VPort NS State Machine events
3279a36c61f9SKrishna Gudipati  */
3280a36c61f9SKrishna Gudipati enum vport_ns_event {
3281a36c61f9SKrishna Gudipati 	NSSM_EVENT_PORT_ONLINE = 1,
3282a36c61f9SKrishna Gudipati 	NSSM_EVENT_PORT_OFFLINE = 2,
3283a36c61f9SKrishna Gudipati 	NSSM_EVENT_PLOGI_SENT = 3,
3284a36c61f9SKrishna Gudipati 	NSSM_EVENT_RSP_OK = 4,
3285a36c61f9SKrishna Gudipati 	NSSM_EVENT_RSP_ERROR = 5,
3286a36c61f9SKrishna Gudipati 	NSSM_EVENT_TIMEOUT = 6,
3287a36c61f9SKrishna Gudipati 	NSSM_EVENT_NS_QUERY = 7,
3288a36c61f9SKrishna Gudipati 	NSSM_EVENT_RSPNID_SENT = 8,
3289a36c61f9SKrishna Gudipati 	NSSM_EVENT_RFTID_SENT = 9,
3290a36c61f9SKrishna Gudipati 	NSSM_EVENT_RFFID_SENT = 10,
3291a36c61f9SKrishna Gudipati 	NSSM_EVENT_GIDFT_SENT = 11,
3292a36c61f9SKrishna Gudipati };
3293a36c61f9SKrishna Gudipati 
3294a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3295a36c61f9SKrishna Gudipati 					   enum vport_ns_event event);
3296a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3297a36c61f9SKrishna Gudipati 						 enum vport_ns_event event);
3298a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3299a36c61f9SKrishna Gudipati 					 enum vport_ns_event event);
3300a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3301a36c61f9SKrishna Gudipati 					       enum vport_ns_event event);
3302a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rspn_id(
3303a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3304a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3305a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3306a36c61f9SKrishna Gudipati 					   enum vport_ns_event event);
3307a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3308a36c61f9SKrishna Gudipati 						 enum vport_ns_event event);
3309a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rft_id(
3310a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3311a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3312a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3313a36c61f9SKrishna Gudipati 						enum vport_ns_event event);
3314a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3315a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
3316a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rff_id(
3317a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3318a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3319a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3320a36c61f9SKrishna Gudipati 						enum vport_ns_event event);
3321a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3322a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
3323a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_gid_ft(
3324a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3325a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3326a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3327a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
3328a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3329a36c61f9SKrishna Gudipati 						enum vport_ns_event event);
3330a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3331a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
33325fbe25c7SJing Huang /*
3333a36c61f9SKrishna Gudipati  *	Start in offline state - awaiting linkup
3334a36c61f9SKrishna Gudipati  */
3335a36c61f9SKrishna Gudipati static void
3336a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3337a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3338a36c61f9SKrishna Gudipati {
3339a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3340a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3341a36c61f9SKrishna Gudipati 
3342a36c61f9SKrishna Gudipati 	switch (event) {
3343a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_ONLINE:
3344a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3345a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_plogi(ns, NULL);
3346a36c61f9SKrishna Gudipati 		break;
3347a36c61f9SKrishna Gudipati 
3348a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3349a36c61f9SKrishna Gudipati 		break;
3350a36c61f9SKrishna Gudipati 
3351a36c61f9SKrishna Gudipati 	default:
3352a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3353a36c61f9SKrishna Gudipati 	}
3354a36c61f9SKrishna Gudipati }
3355a36c61f9SKrishna Gudipati 
3356a36c61f9SKrishna Gudipati static void
3357a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3358a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3359a36c61f9SKrishna Gudipati {
3360a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3361a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3362a36c61f9SKrishna Gudipati 
3363a36c61f9SKrishna Gudipati 	switch (event) {
3364a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PLOGI_SENT:
3365a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi);
3366a36c61f9SKrishna Gudipati 		break;
3367a36c61f9SKrishna Gudipati 
3368a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3369a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3370a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3371a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3372a36c61f9SKrishna Gudipati 		break;
3373a36c61f9SKrishna Gudipati 
3374a36c61f9SKrishna Gudipati 	default:
3375a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3376a36c61f9SKrishna Gudipati 	}
3377a36c61f9SKrishna Gudipati }
3378a36c61f9SKrishna Gudipati 
3379a36c61f9SKrishna Gudipati static void
3380a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3381a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3382a36c61f9SKrishna Gudipati {
3383a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3384a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3385a36c61f9SKrishna Gudipati 
3386a36c61f9SKrishna Gudipati 	switch (event) {
3387a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3388a36c61f9SKrishna Gudipati 		/*
3389a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3390a36c61f9SKrishna Gudipati 		 */
3391a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry);
3392a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3393a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3394a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3395a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3396a36c61f9SKrishna Gudipati 		break;
3397a36c61f9SKrishna Gudipati 
3398a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3399a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3400a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3401a36c61f9SKrishna Gudipati 		break;
3402a36c61f9SKrishna Gudipati 
3403a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3404a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3405a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3406a36c61f9SKrishna Gudipati 		break;
3407a36c61f9SKrishna Gudipati 
3408a36c61f9SKrishna Gudipati 	default:
3409a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3410a36c61f9SKrishna Gudipati 	}
3411a36c61f9SKrishna Gudipati }
3412a36c61f9SKrishna Gudipati 
3413a36c61f9SKrishna Gudipati static void
3414a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3415a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3416a36c61f9SKrishna Gudipati {
3417a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3418a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3419a36c61f9SKrishna Gudipati 
3420a36c61f9SKrishna Gudipati 	switch (event) {
3421a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3422a36c61f9SKrishna Gudipati 		/*
3423a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
3424a36c61f9SKrishna Gudipati 		 */
3425a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3426a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_plogi(ns, NULL);
3427a36c61f9SKrishna Gudipati 		break;
3428a36c61f9SKrishna Gudipati 
3429a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3430a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3431a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3432a36c61f9SKrishna Gudipati 		break;
3433a36c61f9SKrishna Gudipati 
3434a36c61f9SKrishna Gudipati 	default:
3435a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3436a36c61f9SKrishna Gudipati 	}
3437a36c61f9SKrishna Gudipati }
3438a36c61f9SKrishna Gudipati 
3439a36c61f9SKrishna Gudipati static void
3440a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3441a36c61f9SKrishna Gudipati 				   enum vport_ns_event event)
3442a36c61f9SKrishna Gudipati {
3443a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3444a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3445a36c61f9SKrishna Gudipati 
3446a36c61f9SKrishna Gudipati 	switch (event) {
3447a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSPNID_SENT:
3448a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id);
3449a36c61f9SKrishna Gudipati 		break;
3450a36c61f9SKrishna Gudipati 
3451a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3452a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3453a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3454a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3455a36c61f9SKrishna Gudipati 		break;
3456a36c61f9SKrishna Gudipati 
3457a36c61f9SKrishna Gudipati 	default:
3458a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3459a36c61f9SKrishna Gudipati 	}
3460a36c61f9SKrishna Gudipati }
3461a36c61f9SKrishna Gudipati 
3462a36c61f9SKrishna Gudipati static void
3463a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3464a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3465a36c61f9SKrishna Gudipati {
3466a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3467a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3468a36c61f9SKrishna Gudipati 
3469a36c61f9SKrishna Gudipati 	switch (event) {
3470a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3471a36c61f9SKrishna Gudipati 		/*
3472a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3473a36c61f9SKrishna Gudipati 		 */
3474a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry);
3475a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3476a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3477a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3478a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3479a36c61f9SKrishna Gudipati 		break;
3480a36c61f9SKrishna Gudipati 
3481a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3482a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
3483a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rft_id(ns, NULL);
3484a36c61f9SKrishna Gudipati 		break;
3485a36c61f9SKrishna Gudipati 
3486a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3487a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3488a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3489a36c61f9SKrishna Gudipati 		break;
3490a36c61f9SKrishna Gudipati 
3491a36c61f9SKrishna Gudipati 	default:
3492a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3493a36c61f9SKrishna Gudipati 	}
3494a36c61f9SKrishna Gudipati }
3495a36c61f9SKrishna Gudipati 
3496a36c61f9SKrishna Gudipati static void
3497a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3498a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3499a36c61f9SKrishna Gudipati {
3500a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3501a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3502a36c61f9SKrishna Gudipati 
3503a36c61f9SKrishna Gudipati 	switch (event) {
3504a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3505a36c61f9SKrishna Gudipati 		/*
3506a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
3507a36c61f9SKrishna Gudipati 		 */
3508a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3509a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3510a36c61f9SKrishna Gudipati 		break;
3511a36c61f9SKrishna Gudipati 
3512a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3513a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3514a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3515a36c61f9SKrishna Gudipati 		break;
3516a36c61f9SKrishna Gudipati 
3517a36c61f9SKrishna Gudipati 	default:
3518a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3519a36c61f9SKrishna Gudipati 	}
3520a36c61f9SKrishna Gudipati }
3521a36c61f9SKrishna Gudipati 
3522a36c61f9SKrishna Gudipati static void
3523a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns,
3524a36c61f9SKrishna Gudipati 				  enum vport_ns_event event)
3525a36c61f9SKrishna Gudipati {
3526a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3527a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3528a36c61f9SKrishna Gudipati 
3529a36c61f9SKrishna Gudipati 	switch (event) {
3530a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RFTID_SENT:
3531a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id);
3532a36c61f9SKrishna Gudipati 		break;
3533a36c61f9SKrishna Gudipati 
3534a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3535a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3536a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3537a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3538a36c61f9SKrishna Gudipati 		break;
3539a36c61f9SKrishna Gudipati 
3540a36c61f9SKrishna Gudipati 	default:
3541a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3542a36c61f9SKrishna Gudipati 	}
3543a36c61f9SKrishna Gudipati }
3544a36c61f9SKrishna Gudipati 
3545a36c61f9SKrishna Gudipati static void
3546a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3547a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3548a36c61f9SKrishna Gudipati {
3549a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3550a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3551a36c61f9SKrishna Gudipati 
3552a36c61f9SKrishna Gudipati 	switch (event) {
3553a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3554a36c61f9SKrishna Gudipati 		/* Now move to register FC4 Features */
3555a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
3556a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rff_id(ns, NULL);
3557a36c61f9SKrishna Gudipati 		break;
3558a36c61f9SKrishna Gudipati 
3559a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3560a36c61f9SKrishna Gudipati 		/*
3561a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3562a36c61f9SKrishna Gudipati 		 */
3563a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry);
3564a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3565a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3566a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3567a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3568a36c61f9SKrishna Gudipati 		break;
3569a36c61f9SKrishna Gudipati 
3570a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3571a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3572a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3573a36c61f9SKrishna Gudipati 		break;
3574a36c61f9SKrishna Gudipati 
3575a36c61f9SKrishna Gudipati 	default:
3576a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3577a36c61f9SKrishna Gudipati 	}
3578a36c61f9SKrishna Gudipati }
3579a36c61f9SKrishna Gudipati 
3580a36c61f9SKrishna Gudipati static void
3581a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3582a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3583a36c61f9SKrishna Gudipati {
3584a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3585a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3586a36c61f9SKrishna Gudipati 
3587a36c61f9SKrishna Gudipati 	switch (event) {
3588a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3589a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
3590a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rft_id(ns, NULL);
3591a36c61f9SKrishna Gudipati 		break;
3592a36c61f9SKrishna Gudipati 
3593a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3594a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3595a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3596a36c61f9SKrishna Gudipati 		break;
3597a36c61f9SKrishna Gudipati 
3598a36c61f9SKrishna Gudipati 	default:
3599a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3600a36c61f9SKrishna Gudipati 	}
3601a36c61f9SKrishna Gudipati }
3602a36c61f9SKrishna Gudipati 
3603a36c61f9SKrishna Gudipati static void
3604a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns,
3605a36c61f9SKrishna Gudipati 				  enum vport_ns_event event)
3606a36c61f9SKrishna Gudipati {
3607a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3608a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3609a36c61f9SKrishna Gudipati 
3610a36c61f9SKrishna Gudipati 	switch (event) {
3611a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RFFID_SENT:
3612a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id);
3613a36c61f9SKrishna Gudipati 		break;
3614a36c61f9SKrishna Gudipati 
3615a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3616a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3617a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3618a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3619a36c61f9SKrishna Gudipati 		break;
3620a36c61f9SKrishna Gudipati 
3621a36c61f9SKrishna Gudipati 	default:
3622a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3623a36c61f9SKrishna Gudipati 	}
3624a36c61f9SKrishna Gudipati }
3625a36c61f9SKrishna Gudipati 
3626a36c61f9SKrishna Gudipati static void
3627a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3628a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3629a36c61f9SKrishna Gudipati {
3630a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3631a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3632a36c61f9SKrishna Gudipati 
3633a36c61f9SKrishna Gudipati 	switch (event) {
3634a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3635a36c61f9SKrishna Gudipati 
3636a36c61f9SKrishna Gudipati 		/*
3637a36c61f9SKrishna Gudipati 		 * If min cfg mode is enabled, we donot initiate rport
3638a36c61f9SKrishna Gudipati 		 * discovery with the fabric. Instead, we will retrieve the
3639a36c61f9SKrishna Gudipati 		 * boot targets from HAL/FW.
3640a36c61f9SKrishna Gudipati 		 */
3641a36c61f9SKrishna Gudipati 		if (__fcs_min_cfg(ns->port->fcs)) {
3642a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ns_boot_target_disc(ns->port);
3643a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
3644a36c61f9SKrishna Gudipati 			return;
3645a36c61f9SKrishna Gudipati 		}
3646a36c61f9SKrishna Gudipati 
3647a36c61f9SKrishna Gudipati 		/*
3648a36c61f9SKrishna Gudipati 		 * If the port role is Initiator Mode issue NS query.
3649a36c61f9SKrishna Gudipati 		 * If it is Target Mode, skip this and go to online.
3650a36c61f9SKrishna Gudipati 		 */
3651a36c61f9SKrishna Gudipati 		if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
3652a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ns,
3653a36c61f9SKrishna Gudipati 				bfa_fcs_lport_ns_sm_sending_gid_ft);
3654a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3655a36c61f9SKrishna Gudipati 		}
3656a36c61f9SKrishna Gudipati 		/*
3657a36c61f9SKrishna Gudipati 		 * kick off mgmt srvr state machine
3658a36c61f9SKrishna Gudipati 		 */
3659a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_online(ns->port);
3660a36c61f9SKrishna Gudipati 		break;
3661a36c61f9SKrishna Gudipati 
3662a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3663a36c61f9SKrishna Gudipati 		/*
3664a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3665a36c61f9SKrishna Gudipati 		 */
3666a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry);
3667a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3668a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3669a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3670a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3671a36c61f9SKrishna Gudipati 		break;
3672a36c61f9SKrishna Gudipati 
3673a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3674a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3675a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3676a36c61f9SKrishna Gudipati 		break;
3677a36c61f9SKrishna Gudipati 
3678a36c61f9SKrishna Gudipati 	default:
3679a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3680a36c61f9SKrishna Gudipati 	}
3681a36c61f9SKrishna Gudipati }
3682a36c61f9SKrishna Gudipati 
3683a36c61f9SKrishna Gudipati static void
3684a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3685a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3686a36c61f9SKrishna Gudipati {
3687a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3688a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3689a36c61f9SKrishna Gudipati 
3690a36c61f9SKrishna Gudipati 	switch (event) {
3691a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3692a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
3693a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rff_id(ns, NULL);
3694a36c61f9SKrishna Gudipati 		break;
3695a36c61f9SKrishna Gudipati 
3696a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3697a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3698a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3699a36c61f9SKrishna Gudipati 		break;
3700a36c61f9SKrishna Gudipati 
3701a36c61f9SKrishna Gudipati 	default:
3702a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3703a36c61f9SKrishna Gudipati 	}
3704a36c61f9SKrishna Gudipati }
3705a36c61f9SKrishna Gudipati static void
3706a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3707a36c61f9SKrishna Gudipati 				  enum vport_ns_event event)
3708a36c61f9SKrishna Gudipati {
3709a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3710a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3711a36c61f9SKrishna Gudipati 
3712a36c61f9SKrishna Gudipati 	switch (event) {
3713a36c61f9SKrishna Gudipati 	case NSSM_EVENT_GIDFT_SENT:
3714a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft);
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_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3720a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3721a36c61f9SKrishna Gudipati 		break;
3722a36c61f9SKrishna Gudipati 
3723a36c61f9SKrishna Gudipati 	default:
3724a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3725a36c61f9SKrishna Gudipati 	}
3726a36c61f9SKrishna Gudipati }
3727a36c61f9SKrishna Gudipati 
3728a36c61f9SKrishna Gudipati static void
3729a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3730a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3731a36c61f9SKrishna Gudipati {
3732a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3733a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3734a36c61f9SKrishna Gudipati 
3735a36c61f9SKrishna Gudipati 	switch (event) {
3736a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3737a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
3738a36c61f9SKrishna Gudipati 		break;
3739a36c61f9SKrishna Gudipati 
3740a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3741a36c61f9SKrishna Gudipati 		/*
3742a36c61f9SKrishna Gudipati 		 * TBD: for certain reject codes, we don't need to retry
3743a36c61f9SKrishna Gudipati 		 */
3744a36c61f9SKrishna Gudipati 		/*
3745a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3746a36c61f9SKrishna Gudipati 		 */
3747a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry);
3748a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3749a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3750a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3751a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3752a36c61f9SKrishna Gudipati 		break;
3753a36c61f9SKrishna Gudipati 
3754a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3755a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3756a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3757a36c61f9SKrishna Gudipati 		break;
3758a36c61f9SKrishna Gudipati 
3759a36c61f9SKrishna Gudipati 	case  NSSM_EVENT_NS_QUERY:
3760a36c61f9SKrishna Gudipati 		break;
3761a36c61f9SKrishna Gudipati 
3762a36c61f9SKrishna Gudipati 	default:
3763a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3764a36c61f9SKrishna Gudipati 	}
3765a36c61f9SKrishna Gudipati }
3766a36c61f9SKrishna Gudipati 
3767a36c61f9SKrishna Gudipati static void
3768a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3769a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3770a36c61f9SKrishna Gudipati {
3771a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3772a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3773a36c61f9SKrishna Gudipati 
3774a36c61f9SKrishna Gudipati 	switch (event) {
3775a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3776a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft);
3777a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3778a36c61f9SKrishna Gudipati 		break;
3779a36c61f9SKrishna Gudipati 
3780a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3781a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3782a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3783a36c61f9SKrishna Gudipati 		break;
3784a36c61f9SKrishna Gudipati 
3785a36c61f9SKrishna Gudipati 	default:
3786a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3787a36c61f9SKrishna Gudipati 	}
3788a36c61f9SKrishna Gudipati }
3789a36c61f9SKrishna Gudipati 
3790a36c61f9SKrishna Gudipati static void
3791a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3792a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3793a36c61f9SKrishna Gudipati {
3794a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3795a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3796a36c61f9SKrishna Gudipati 
3797a36c61f9SKrishna Gudipati 	switch (event) {
3798a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3799a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3800a36c61f9SKrishna Gudipati 		break;
3801a36c61f9SKrishna Gudipati 
3802a36c61f9SKrishna Gudipati 	case NSSM_EVENT_NS_QUERY:
3803a36c61f9SKrishna Gudipati 		/*
3804a36c61f9SKrishna Gudipati 		 * If the port role is Initiator Mode issue NS query.
3805a36c61f9SKrishna Gudipati 		 * If it is Target Mode, skip this and go to online.
3806a36c61f9SKrishna Gudipati 		 */
3807a36c61f9SKrishna Gudipati 		if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
3808a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ns,
3809a36c61f9SKrishna Gudipati 				bfa_fcs_lport_ns_sm_sending_gid_ft);
3810a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3811a36c61f9SKrishna Gudipati 		};
3812a36c61f9SKrishna Gudipati 		break;
3813a36c61f9SKrishna Gudipati 
3814a36c61f9SKrishna Gudipati 	default:
3815a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3816a36c61f9SKrishna Gudipati 	}
3817a36c61f9SKrishna Gudipati }
3818a36c61f9SKrishna Gudipati 
3819a36c61f9SKrishna Gudipati 
3820a36c61f9SKrishna Gudipati 
38215fbe25c7SJing Huang /*
3822a36c61f9SKrishna Gudipati  *  ns_pvt Nameserver local functions
3823a36c61f9SKrishna Gudipati  */
3824a36c61f9SKrishna Gudipati 
3825a36c61f9SKrishna Gudipati static void
3826a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3827a36c61f9SKrishna Gudipati {
3828a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3829a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
3830a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
3831a36c61f9SKrishna Gudipati 	int             len;
3832a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3833a36c61f9SKrishna Gudipati 
3834a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
3835a36c61f9SKrishna Gudipati 
3836c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
3837c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3838a36c61f9SKrishna Gudipati 	if (!fcxp) {
3839a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_alloc_wait++;
3840a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3841c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ns_send_plogi, ns, BFA_TRUE);
3842a36c61f9SKrishna Gudipati 		return;
3843a36c61f9SKrishna Gudipati 	}
3844a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
3845a36c61f9SKrishna Gudipati 
3846a36c61f9SKrishna Gudipati 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3847f16a1750SMaggie Zhang 			     bfa_hton3b(FC_NAME_SERVER),
3848a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port), 0,
3849a36c61f9SKrishna Gudipati 			     port->port_cfg.pwwn, port->port_cfg.nwwn,
3850be540a99SKrishna Gudipati 			     bfa_fcport_get_maxfrsize(port->fcs->bfa),
3851be540a99SKrishna Gudipati 			     bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
3852a36c61f9SKrishna Gudipati 
3853a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3854a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3855a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_plogi_response, (void *)ns,
3856a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_ELS_TOV);
3857a36c61f9SKrishna Gudipati 	port->stats.ns_plogi_sent++;
3858a36c61f9SKrishna Gudipati 
3859a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
3860a36c61f9SKrishna Gudipati }
3861a36c61f9SKrishna Gudipati 
3862a36c61f9SKrishna Gudipati static void
3863a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3864a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
3865a36c61f9SKrishna Gudipati 		       u32 resid_len, struct fchs_s *rsp_fchs)
3866a36c61f9SKrishna Gudipati {
3867a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3868a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
3869a36c61f9SKrishna Gudipati 	/* struct fc_logi_s *plogi_resp; */
3870a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd;
3871a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
3872a36c61f9SKrishna Gudipati 
3873a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
3874a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3875a36c61f9SKrishna Gudipati 
3876a36c61f9SKrishna Gudipati 	/*
3877a36c61f9SKrishna Gudipati 	 * Sanity Checks
3878a36c61f9SKrishna Gudipati 	 */
3879a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3880a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
3881a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_rsp_err++;
3882a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3883a36c61f9SKrishna Gudipati 		return;
3884a36c61f9SKrishna Gudipati 	}
3885a36c61f9SKrishna Gudipati 
3886a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
3887a36c61f9SKrishna Gudipati 
3888a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
3889a36c61f9SKrishna Gudipati 
3890a36c61f9SKrishna Gudipati 	case FC_ELS_ACC:
3891a36c61f9SKrishna Gudipati 		if (rsp_len < sizeof(struct fc_logi_s)) {
3892a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rsp_len);
3893a36c61f9SKrishna Gudipati 			port->stats.ns_plogi_acc_err++;
3894a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3895a36c61f9SKrishna Gudipati 			break;
3896a36c61f9SKrishna Gudipati 		}
3897a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_accepts++;
3898a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
3899a36c61f9SKrishna Gudipati 		break;
3900a36c61f9SKrishna Gudipati 
3901a36c61f9SKrishna Gudipati 	case FC_ELS_LS_RJT:
3902a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3903a36c61f9SKrishna Gudipati 
3904a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code);
3905a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code_expl);
3906a36c61f9SKrishna Gudipati 
3907a36c61f9SKrishna Gudipati 		port->stats.ns_rejects++;
3908a36c61f9SKrishna Gudipati 
3909a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3910a36c61f9SKrishna Gudipati 		break;
3911a36c61f9SKrishna Gudipati 
3912a36c61f9SKrishna Gudipati 	default:
3913a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_unknown_rsp++;
3914a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, els_cmd->els_code);
3915a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
3916a36c61f9SKrishna Gudipati 	}
3917a36c61f9SKrishna Gudipati }
3918a36c61f9SKrishna Gudipati 
39195fbe25c7SJing Huang /*
3920a36c61f9SKrishna Gudipati  * Register the symbolic port name.
3921a36c61f9SKrishna Gudipati  */
3922a36c61f9SKrishna Gudipati static void
3923a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3924a36c61f9SKrishna Gudipati {
3925a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
3926a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
3927a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
3928a36c61f9SKrishna Gudipati 	int             len;
3929a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3930a36c61f9SKrishna Gudipati 	u8         symbl[256];
3931a36c61f9SKrishna Gudipati 	u8         *psymbl = &symbl[0];
3932a36c61f9SKrishna Gudipati 
39336a18b167SJing Huang 	memset(symbl, 0, sizeof(symbl));
3934a36c61f9SKrishna Gudipati 
3935a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3936a36c61f9SKrishna Gudipati 
3937c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
3938c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3939a36c61f9SKrishna Gudipati 	if (!fcxp) {
3940a36c61f9SKrishna Gudipati 		port->stats.ns_rspnid_alloc_wait++;
3941a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3942c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ns_send_rspn_id, ns, BFA_TRUE);
3943a36c61f9SKrishna Gudipati 		return;
3944a36c61f9SKrishna Gudipati 	}
3945a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
3946a36c61f9SKrishna Gudipati 
3947a36c61f9SKrishna Gudipati 	/*
3948a36c61f9SKrishna Gudipati 	 * for V-Port, form a Port Symbolic Name
3949a36c61f9SKrishna Gudipati 	 */
3950a36c61f9SKrishna Gudipati 	if (port->vport) {
39515fbe25c7SJing Huang 		/*
3952a36c61f9SKrishna Gudipati 		 * For Vports, we append the vport's port symbolic name
3953a36c61f9SKrishna Gudipati 		 * to that of the base port.
3954a36c61f9SKrishna Gudipati 		 */
3955a36c61f9SKrishna Gudipati 
3956a36c61f9SKrishna Gudipati 		strncpy((char *)psymbl,
3957a36c61f9SKrishna Gudipati 			(char *) &
3958a36c61f9SKrishna Gudipati 			(bfa_fcs_lport_get_psym_name
3959a36c61f9SKrishna Gudipati 			 (bfa_fcs_get_base_port(port->fcs))),
3960a36c61f9SKrishna Gudipati 			strlen((char *) &
3961a36c61f9SKrishna Gudipati 			       bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3962a36c61f9SKrishna Gudipati 							  (port->fcs))));
3963a36c61f9SKrishna Gudipati 
3964a36c61f9SKrishna Gudipati 		/* Ensure we have a null terminating string. */
3965a36c61f9SKrishna Gudipati 		((char *)psymbl)[strlen((char *) &
3966a36c61f9SKrishna Gudipati 			bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
3967a36c61f9SKrishna Gudipati 						(port->fcs)))] = 0;
3968a36c61f9SKrishna Gudipati 		strncat((char *)psymbl,
3969a36c61f9SKrishna Gudipati 			(char *) &(bfa_fcs_lport_get_psym_name(port)),
3970a36c61f9SKrishna Gudipati 		strlen((char *) &bfa_fcs_lport_get_psym_name(port)));
3971a36c61f9SKrishna Gudipati 	} else {
3972a36c61f9SKrishna Gudipati 		psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port));
3973a36c61f9SKrishna Gudipati 	}
3974a36c61f9SKrishna Gudipati 
3975a36c61f9SKrishna Gudipati 	len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3976a36c61f9SKrishna Gudipati 			      bfa_fcs_lport_get_fcid(port), 0, psymbl);
3977a36c61f9SKrishna Gudipati 
3978a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3979a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3980a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_rspn_id_response, (void *)ns,
3981a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
3982a36c61f9SKrishna Gudipati 
3983a36c61f9SKrishna Gudipati 	port->stats.ns_rspnid_sent++;
3984a36c61f9SKrishna Gudipati 
3985a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
3986a36c61f9SKrishna Gudipati }
3987a36c61f9SKrishna Gudipati 
3988a36c61f9SKrishna Gudipati static void
3989a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3990a36c61f9SKrishna Gudipati 				 void *cbarg, bfa_status_t req_status,
3991a36c61f9SKrishna Gudipati 				 u32 rsp_len, u32 resid_len,
3992a36c61f9SKrishna Gudipati 				 struct fchs_s *rsp_fchs)
3993a36c61f9SKrishna Gudipati {
3994a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
3995a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
3996a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
3997a36c61f9SKrishna Gudipati 
3998a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3999a36c61f9SKrishna Gudipati 
4000a36c61f9SKrishna Gudipati 	/*
4001a36c61f9SKrishna Gudipati 	 * Sanity Checks
4002a36c61f9SKrishna Gudipati 	 */
4003a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4004a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4005a36c61f9SKrishna Gudipati 		port->stats.ns_rspnid_rsp_err++;
4006a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4007a36c61f9SKrishna Gudipati 		return;
4008a36c61f9SKrishna Gudipati 	}
4009a36c61f9SKrishna Gudipati 
4010a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4011ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4012a36c61f9SKrishna Gudipati 
4013a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4014a36c61f9SKrishna Gudipati 		port->stats.ns_rspnid_accepts++;
4015a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4016a36c61f9SKrishna Gudipati 		return;
4017a36c61f9SKrishna Gudipati 	}
4018a36c61f9SKrishna Gudipati 
4019a36c61f9SKrishna Gudipati 	port->stats.ns_rspnid_rejects++;
4020a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
4021a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
4022a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4023a36c61f9SKrishna Gudipati }
4024a36c61f9SKrishna Gudipati 
40255fbe25c7SJing Huang /*
4026a36c61f9SKrishna Gudipati  * Register FC4-Types
4027a36c61f9SKrishna Gudipati  */
4028a36c61f9SKrishna Gudipati static void
4029a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4030a36c61f9SKrishna Gudipati {
4031a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4032a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4033a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4034a36c61f9SKrishna Gudipati 	int             len;
4035a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4036a36c61f9SKrishna Gudipati 
4037a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4038a36c61f9SKrishna Gudipati 
4039c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4040c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4041a36c61f9SKrishna Gudipati 	if (!fcxp) {
4042a36c61f9SKrishna Gudipati 		port->stats.ns_rftid_alloc_wait++;
4043a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4044c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ns_send_rft_id, ns, BFA_TRUE);
4045a36c61f9SKrishna Gudipati 		return;
4046a36c61f9SKrishna Gudipati 	}
4047a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
4048a36c61f9SKrishna Gudipati 
4049a36c61f9SKrishna Gudipati 	len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4050a36c61f9SKrishna Gudipati 		     bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles);
4051a36c61f9SKrishna Gudipati 
4052a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4053a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4054a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_rft_id_response, (void *)ns,
4055a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
4056a36c61f9SKrishna Gudipati 
4057a36c61f9SKrishna Gudipati 	port->stats.ns_rftid_sent++;
4058a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
4059a36c61f9SKrishna Gudipati }
4060a36c61f9SKrishna Gudipati 
4061a36c61f9SKrishna Gudipati static void
4062a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4063a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
4064a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
4065a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4066a36c61f9SKrishna Gudipati {
4067a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4068a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4069a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
4070a36c61f9SKrishna Gudipati 
4071a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4072a36c61f9SKrishna Gudipati 
4073a36c61f9SKrishna Gudipati 	/*
4074a36c61f9SKrishna Gudipati 	 * Sanity Checks
4075a36c61f9SKrishna Gudipati 	 */
4076a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4077a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4078a36c61f9SKrishna Gudipati 		port->stats.ns_rftid_rsp_err++;
4079a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4080a36c61f9SKrishna Gudipati 		return;
4081a36c61f9SKrishna Gudipati 	}
4082a36c61f9SKrishna Gudipati 
4083a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4084ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4085a36c61f9SKrishna Gudipati 
4086a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4087a36c61f9SKrishna Gudipati 		port->stats.ns_rftid_accepts++;
4088a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4089a36c61f9SKrishna Gudipati 		return;
4090a36c61f9SKrishna Gudipati 	}
4091a36c61f9SKrishna Gudipati 
4092a36c61f9SKrishna Gudipati 	port->stats.ns_rftid_rejects++;
4093a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
4094a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
4095a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4096a36c61f9SKrishna Gudipati }
4097a36c61f9SKrishna Gudipati 
40985fbe25c7SJing Huang /*
4099a36c61f9SKrishna Gudipati  * Register FC4-Features : Should be done after RFT_ID
4100a36c61f9SKrishna Gudipati  */
4101a36c61f9SKrishna Gudipati static void
4102a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4103a36c61f9SKrishna Gudipati {
4104a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4105a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4106a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4107a36c61f9SKrishna Gudipati 	int             len;
4108a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4109a36c61f9SKrishna Gudipati 	u8			fc4_ftrs = 0;
4110a36c61f9SKrishna Gudipati 
4111a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4112a36c61f9SKrishna Gudipati 
4113c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4114c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4115a36c61f9SKrishna Gudipati 	if (!fcxp) {
4116a36c61f9SKrishna Gudipati 		port->stats.ns_rffid_alloc_wait++;
4117a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4118c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ns_send_rff_id, ns, BFA_TRUE);
4119a36c61f9SKrishna Gudipati 		return;
4120a36c61f9SKrishna Gudipati 	}
4121a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
4122a36c61f9SKrishna Gudipati 
4123a36c61f9SKrishna Gudipati 	if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port))
4124a36c61f9SKrishna Gudipati 		fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
4125a36c61f9SKrishna Gudipati 
4126a36c61f9SKrishna Gudipati 	len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4127a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port), 0,
4128a36c61f9SKrishna Gudipati 				 FC_TYPE_FCP, fc4_ftrs);
4129a36c61f9SKrishna Gudipati 
4130a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4131a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4132a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_rff_id_response, (void *)ns,
4133a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
4134a36c61f9SKrishna Gudipati 
4135a36c61f9SKrishna Gudipati 	port->stats.ns_rffid_sent++;
4136a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
4137a36c61f9SKrishna Gudipati }
4138a36c61f9SKrishna Gudipati 
4139a36c61f9SKrishna Gudipati static void
4140a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4141a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
4142a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
4143a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4144a36c61f9SKrishna Gudipati {
4145a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4146a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4147a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
4148a36c61f9SKrishna Gudipati 
4149a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4150a36c61f9SKrishna Gudipati 
4151a36c61f9SKrishna Gudipati 	/*
4152a36c61f9SKrishna Gudipati 	 * Sanity Checks
4153a36c61f9SKrishna Gudipati 	 */
4154a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4155a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4156a36c61f9SKrishna Gudipati 		port->stats.ns_rffid_rsp_err++;
4157a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4158a36c61f9SKrishna Gudipati 		return;
4159a36c61f9SKrishna Gudipati 	}
4160a36c61f9SKrishna Gudipati 
4161a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4162ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4163a36c61f9SKrishna Gudipati 
4164a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4165a36c61f9SKrishna Gudipati 		port->stats.ns_rffid_accepts++;
4166a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4167a36c61f9SKrishna Gudipati 		return;
4168a36c61f9SKrishna Gudipati 	}
4169a36c61f9SKrishna Gudipati 
4170a36c61f9SKrishna Gudipati 	port->stats.ns_rffid_rejects++;
4171a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
4172a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
4173a36c61f9SKrishna Gudipati 
4174a36c61f9SKrishna Gudipati 	if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
4175a36c61f9SKrishna Gudipati 		/* if this command is not supported, we don't retry */
4176a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4177a36c61f9SKrishna Gudipati 	} else
4178a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4179a36c61f9SKrishna Gudipati }
41805fbe25c7SJing Huang /*
4181a36c61f9SKrishna Gudipati  * Query Fabric for FC4-Types Devices.
4182a36c61f9SKrishna Gudipati  *
4183a36c61f9SKrishna Gudipati * TBD : Need to use a local (FCS private) response buffer, since the response
4184a36c61f9SKrishna Gudipati  * can be larger than 2K.
4185a36c61f9SKrishna Gudipati  */
4186a36c61f9SKrishna Gudipati static void
4187a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4188a36c61f9SKrishna Gudipati {
4189a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4190a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4191a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4192a36c61f9SKrishna Gudipati 	int             len;
4193a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4194a36c61f9SKrishna Gudipati 
4195a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
4196a36c61f9SKrishna Gudipati 
4197c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4198c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4199a36c61f9SKrishna Gudipati 	if (!fcxp) {
4200a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_alloc_wait++;
4201a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4202c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ns_send_gid_ft, ns, BFA_TRUE);
4203a36c61f9SKrishna Gudipati 		return;
4204a36c61f9SKrishna Gudipati 	}
4205a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
4206a36c61f9SKrishna Gudipati 
4207a36c61f9SKrishna Gudipati 	/*
4208a36c61f9SKrishna Gudipati 	 * This query is only initiated for FCP initiator mode.
4209a36c61f9SKrishna Gudipati 	 */
4210a36c61f9SKrishna Gudipati 	len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4211a36c61f9SKrishna Gudipati 			      ns->port->pid, FC_TYPE_FCP);
4212a36c61f9SKrishna Gudipati 
4213a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4214a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4215a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_gid_ft_response, (void *)ns,
4216a36c61f9SKrishna Gudipati 			  bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV);
4217a36c61f9SKrishna Gudipati 
4218a36c61f9SKrishna Gudipati 	port->stats.ns_gidft_sent++;
4219a36c61f9SKrishna Gudipati 
4220a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
4221a36c61f9SKrishna Gudipati }
4222a36c61f9SKrishna Gudipati 
4223a36c61f9SKrishna Gudipati static void
4224a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4225a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
4226a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
4227a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4228a36c61f9SKrishna Gudipati {
4229a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4230a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4231a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
4232a36c61f9SKrishna Gudipati 	u32        n_pids;
4233a36c61f9SKrishna Gudipati 
4234a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4235a36c61f9SKrishna Gudipati 
4236a36c61f9SKrishna Gudipati 	/*
4237a36c61f9SKrishna Gudipati 	 * Sanity Checks
4238a36c61f9SKrishna Gudipati 	 */
4239a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4240a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4241a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_rsp_err++;
4242a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4243a36c61f9SKrishna Gudipati 		return;
4244a36c61f9SKrishna Gudipati 	}
4245a36c61f9SKrishna Gudipati 
4246a36c61f9SKrishna Gudipati 	if (resid_len != 0) {
4247a36c61f9SKrishna Gudipati 		/*
4248a36c61f9SKrishna Gudipati 		 * TBD : we will need to allocate a larger buffer & retry the
4249a36c61f9SKrishna Gudipati 		 * command
4250a36c61f9SKrishna Gudipati 		 */
4251a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rsp_len);
4252a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, resid_len);
4253a36c61f9SKrishna Gudipati 		return;
4254a36c61f9SKrishna Gudipati 	}
4255a36c61f9SKrishna Gudipati 
4256a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4257ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4258a36c61f9SKrishna Gudipati 
4259a36c61f9SKrishna Gudipati 	switch (cthdr->cmd_rsp_code) {
4260a36c61f9SKrishna Gudipati 
4261a36c61f9SKrishna Gudipati 	case CT_RSP_ACCEPT:
4262a36c61f9SKrishna Gudipati 
4263a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_accepts++;
4264a36c61f9SKrishna Gudipati 		n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
4265a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, n_pids);
4266a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_process_gidft_pids(port,
4267a36c61f9SKrishna Gudipati 						   (u32 *) (cthdr + 1),
4268a36c61f9SKrishna Gudipati 						   n_pids);
4269a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4270a36c61f9SKrishna Gudipati 		break;
4271a36c61f9SKrishna Gudipati 
4272a36c61f9SKrishna Gudipati 	case CT_RSP_REJECT:
4273a36c61f9SKrishna Gudipati 
4274a36c61f9SKrishna Gudipati 		/*
4275a36c61f9SKrishna Gudipati 		 * Check the reason code  & explanation.
4276a36c61f9SKrishna Gudipati 		 * There may not have been any FC4 devices in the fabric
4277a36c61f9SKrishna Gudipati 		 */
4278a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_rejects++;
4279a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, cthdr->reason_code);
4280a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, cthdr->exp_code);
4281a36c61f9SKrishna Gudipati 
4282a36c61f9SKrishna Gudipati 		if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
4283a36c61f9SKrishna Gudipati 		    && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
4284a36c61f9SKrishna Gudipati 
4285a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4286a36c61f9SKrishna Gudipati 		} else {
4287a36c61f9SKrishna Gudipati 			/*
4288a36c61f9SKrishna Gudipati 			 * for all other errors, retry
4289a36c61f9SKrishna Gudipati 			 */
4290a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4291a36c61f9SKrishna Gudipati 		}
4292a36c61f9SKrishna Gudipati 		break;
4293a36c61f9SKrishna Gudipati 
4294a36c61f9SKrishna Gudipati 	default:
4295a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_unknown_rsp++;
4296a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, cthdr->cmd_rsp_code);
4297a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4298a36c61f9SKrishna Gudipati 	}
4299a36c61f9SKrishna Gudipati }
4300a36c61f9SKrishna Gudipati 
43015fbe25c7SJing Huang /*
4302a36c61f9SKrishna Gudipati  *     This routine will be called by bfa_timer on timer timeouts.
4303a36c61f9SKrishna Gudipati  *
4304a36c61f9SKrishna Gudipati  *	param[in]	port - pointer to bfa_fcs_lport_t.
4305a36c61f9SKrishna Gudipati  *
4306a36c61f9SKrishna Gudipati  *	return
4307a36c61f9SKrishna Gudipati  *		void
4308a36c61f9SKrishna Gudipati  *
4309a36c61f9SKrishna Gudipati  *	Special Considerations:
4310a36c61f9SKrishna Gudipati  *
4311a36c61f9SKrishna Gudipati  *	note
4312a36c61f9SKrishna Gudipati  */
4313a36c61f9SKrishna Gudipati static void
4314a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_timeout(void *arg)
4315a36c61f9SKrishna Gudipati {
4316a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg;
4317a36c61f9SKrishna Gudipati 
4318a36c61f9SKrishna Gudipati 	ns->port->stats.ns_timeouts++;
4319a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
4320a36c61f9SKrishna Gudipati }
4321a36c61f9SKrishna Gudipati 
4322a36c61f9SKrishna Gudipati /*
4323a36c61f9SKrishna Gudipati  * Process the PID list in GID_FT response
4324a36c61f9SKrishna Gudipati  */
4325a36c61f9SKrishna Gudipati static void
4326a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf,
4327a36c61f9SKrishna Gudipati 				   u32 n_pids)
4328a36c61f9SKrishna Gudipati {
4329a36c61f9SKrishna Gudipati 	struct fcgs_gidft_resp_s *gidft_entry;
4330a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
4331a36c61f9SKrishna Gudipati 	u32        ii;
4332a36c61f9SKrishna Gudipati 
4333a36c61f9SKrishna Gudipati 	for (ii = 0; ii < n_pids; ii++) {
4334a36c61f9SKrishna Gudipati 		gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
4335a36c61f9SKrishna Gudipati 
4336a36c61f9SKrishna Gudipati 		if (gidft_entry->pid == port->pid)
4337a36c61f9SKrishna Gudipati 			continue;
4338a36c61f9SKrishna Gudipati 
4339a36c61f9SKrishna Gudipati 		/*
4340a36c61f9SKrishna Gudipati 		 * Check if this rport already exists
4341a36c61f9SKrishna Gudipati 		 */
4342a36c61f9SKrishna Gudipati 		rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid);
4343a36c61f9SKrishna Gudipati 		if (rport == NULL) {
4344a36c61f9SKrishna Gudipati 			/*
4345a36c61f9SKrishna Gudipati 			 * this is a new device. create rport
4346a36c61f9SKrishna Gudipati 			 */
4347a36c61f9SKrishna Gudipati 			rport = bfa_fcs_rport_create(port, gidft_entry->pid);
4348a36c61f9SKrishna Gudipati 		} else {
4349a36c61f9SKrishna Gudipati 			/*
4350a36c61f9SKrishna Gudipati 			 * this rport already exists
4351a36c61f9SKrishna Gudipati 			 */
4352a36c61f9SKrishna Gudipati 			bfa_fcs_rport_scn(rport);
4353a36c61f9SKrishna Gudipati 		}
4354a36c61f9SKrishna Gudipati 
4355a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, gidft_entry->pid);
4356a36c61f9SKrishna Gudipati 
4357a36c61f9SKrishna Gudipati 		/*
4358a36c61f9SKrishna Gudipati 		 * if the last entry bit is set, bail out.
4359a36c61f9SKrishna Gudipati 		 */
4360a36c61f9SKrishna Gudipati 		if (gidft_entry->last)
4361a36c61f9SKrishna Gudipati 			return;
4362a36c61f9SKrishna Gudipati 	}
4363a36c61f9SKrishna Gudipati }
4364a36c61f9SKrishna Gudipati 
43655fbe25c7SJing Huang /*
4366a36c61f9SKrishna Gudipati  *  fcs_ns_public FCS nameserver public interfaces
4367a36c61f9SKrishna Gudipati  */
4368a36c61f9SKrishna Gudipati 
4369a36c61f9SKrishna Gudipati /*
4370a36c61f9SKrishna Gudipati  * Functions called by port/fab.
4371a36c61f9SKrishna Gudipati  * These will send relevant Events to the ns state machine.
4372a36c61f9SKrishna Gudipati  */
4373a36c61f9SKrishna Gudipati void
4374a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port)
4375a36c61f9SKrishna Gudipati {
4376a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4377a36c61f9SKrishna Gudipati 
4378a36c61f9SKrishna Gudipati 	ns->port = port;
4379a36c61f9SKrishna Gudipati 	bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4380a36c61f9SKrishna Gudipati }
4381a36c61f9SKrishna Gudipati 
4382a36c61f9SKrishna Gudipati void
4383a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port)
4384a36c61f9SKrishna Gudipati {
4385a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4386a36c61f9SKrishna Gudipati 
4387a36c61f9SKrishna Gudipati 	ns->port = port;
4388a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
4389a36c61f9SKrishna Gudipati }
4390a36c61f9SKrishna Gudipati 
4391a36c61f9SKrishna Gudipati void
4392a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port)
4393a36c61f9SKrishna Gudipati {
4394a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4395a36c61f9SKrishna Gudipati 
4396a36c61f9SKrishna Gudipati 	ns->port = port;
4397a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
4398a36c61f9SKrishna Gudipati }
4399a36c61f9SKrishna Gudipati 
4400a36c61f9SKrishna Gudipati void
4401a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port)
4402a36c61f9SKrishna Gudipati {
4403a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4404a36c61f9SKrishna Gudipati 
4405a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
4406a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
4407a36c61f9SKrishna Gudipati }
4408a36c61f9SKrishna Gudipati 
440952f94b6fSMaggie static void
4410a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
4411a36c61f9SKrishna Gudipati {
4412a36c61f9SKrishna Gudipati 
4413a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
4414a36c61f9SKrishna Gudipati 	u8 nwwns;
4415a36c61f9SKrishna Gudipati 	wwn_t  wwns[BFA_PREBOOT_BOOTLUN_MAX];
4416a36c61f9SKrishna Gudipati 	int ii;
4417a36c61f9SKrishna Gudipati 
4418a36c61f9SKrishna Gudipati 	bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns);
4419a36c61f9SKrishna Gudipati 
4420a36c61f9SKrishna Gudipati 	for (ii = 0 ; ii < nwwns; ++ii) {
4421a36c61f9SKrishna Gudipati 		rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
4422d4b671c5SJing Huang 		WARN_ON(!rport);
4423a36c61f9SKrishna Gudipati 	}
4424a36c61f9SKrishna Gudipati }
4425a36c61f9SKrishna Gudipati 
4426ebfe8392SKrishna Gudipati void
4427ebfe8392SKrishna Gudipati bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced)
4428ebfe8392SKrishna Gudipati {
4429ebfe8392SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = cbarg;
4430ebfe8392SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4431ebfe8392SKrishna Gudipati 	struct fchs_s fchs;
4432ebfe8392SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4433ebfe8392SKrishna Gudipati 	u8 symbl[256];
4434ebfe8392SKrishna Gudipati 	u8 *psymbl = &symbl[0];
4435ebfe8392SKrishna Gudipati 	int len;
4436ebfe8392SKrishna Gudipati 
4437ebfe8392SKrishna Gudipati 	if (!bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
4438ebfe8392SKrishna Gudipati 		return;
4439ebfe8392SKrishna Gudipati 
4440ebfe8392SKrishna Gudipati 	/* Avoid sending RSPN in the following states. */
4441ebfe8392SKrishna Gudipati 	if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) ||
4442ebfe8392SKrishna Gudipati 	    bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) ||
4443ebfe8392SKrishna Gudipati 	    bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi) ||
4444ebfe8392SKrishna Gudipati 	    bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_retry) ||
4445ebfe8392SKrishna Gudipati 	    bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry))
4446ebfe8392SKrishna Gudipati 		return;
4447ebfe8392SKrishna Gudipati 
4448ebfe8392SKrishna Gudipati 	memset(symbl, 0, sizeof(symbl));
4449ebfe8392SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4450ebfe8392SKrishna Gudipati 
4451c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4452c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
4453ebfe8392SKrishna Gudipati 	if (!fcxp) {
4454ebfe8392SKrishna Gudipati 		port->stats.ns_rspnid_alloc_wait++;
4455ebfe8392SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4456c3f1b123SKrishna Gudipati 			bfa_fcs_lport_ns_util_send_rspn_id, ns, BFA_FALSE);
4457ebfe8392SKrishna Gudipati 		return;
4458ebfe8392SKrishna Gudipati 	}
4459ebfe8392SKrishna Gudipati 
4460ebfe8392SKrishna Gudipati 	ns->fcxp = fcxp;
4461ebfe8392SKrishna Gudipati 
4462ebfe8392SKrishna Gudipati 	if (port->vport) {
4463ebfe8392SKrishna Gudipati 		/*
4464ebfe8392SKrishna Gudipati 		 * For Vports, we append the vport's port symbolic name
4465ebfe8392SKrishna Gudipati 		 * to that of the base port.
4466ebfe8392SKrishna Gudipati 		 */
4467ebfe8392SKrishna Gudipati 		strncpy((char *)psymbl, (char *)&(bfa_fcs_lport_get_psym_name
4468ebfe8392SKrishna Gudipati 			(bfa_fcs_get_base_port(port->fcs))),
4469ebfe8392SKrishna Gudipati 			strlen((char *)&bfa_fcs_lport_get_psym_name(
4470ebfe8392SKrishna Gudipati 			bfa_fcs_get_base_port(port->fcs))));
4471ebfe8392SKrishna Gudipati 
4472ebfe8392SKrishna Gudipati 		/* Ensure we have a null terminating string. */
4473ebfe8392SKrishna Gudipati 		((char *)psymbl)[strlen((char *)&bfa_fcs_lport_get_psym_name(
4474ebfe8392SKrishna Gudipati 		 bfa_fcs_get_base_port(port->fcs)))] = 0;
4475ebfe8392SKrishna Gudipati 
4476ebfe8392SKrishna Gudipati 		strncat((char *)psymbl,
4477ebfe8392SKrishna Gudipati 			(char *)&(bfa_fcs_lport_get_psym_name(port)),
4478ebfe8392SKrishna Gudipati 			strlen((char *)&bfa_fcs_lport_get_psym_name(port)));
4479ebfe8392SKrishna Gudipati 	}
4480ebfe8392SKrishna Gudipati 
4481ebfe8392SKrishna Gudipati 	len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4482ebfe8392SKrishna Gudipati 			      bfa_fcs_lport_get_fcid(port), 0, psymbl);
4483ebfe8392SKrishna Gudipati 
4484ebfe8392SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4485ebfe8392SKrishna Gudipati 		      FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
4486ebfe8392SKrishna Gudipati 
4487ebfe8392SKrishna Gudipati 	port->stats.ns_rspnid_sent++;
4488ebfe8392SKrishna Gudipati }
4489ebfe8392SKrishna Gudipati 
44905fbe25c7SJing Huang /*
4491a36c61f9SKrishna Gudipati  * FCS SCN
4492a36c61f9SKrishna Gudipati  */
4493a36c61f9SKrishna Gudipati 
4494a36c61f9SKrishna Gudipati #define FC_QOS_RSCN_EVENT		0x0c
4495a36c61f9SKrishna Gudipati #define FC_FABRIC_NAME_RSCN_EVENT	0x0d
4496a36c61f9SKrishna Gudipati 
4497a36c61f9SKrishna Gudipati /*
4498a36c61f9SKrishna Gudipati  * forward declarations
4499a36c61f9SKrishna Gudipati  */
4500a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_send_scr(void *scn_cbarg,
4501a36c61f9SKrishna Gudipati 					  struct bfa_fcxp_s *fcxp_alloced);
4502a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_scr_response(void *fcsarg,
4503a36c61f9SKrishna Gudipati 					      struct bfa_fcxp_s *fcxp,
4504a36c61f9SKrishna Gudipati 					      void *cbarg,
4505a36c61f9SKrishna Gudipati 					      bfa_status_t req_status,
4506a36c61f9SKrishna Gudipati 					      u32 rsp_len,
4507a36c61f9SKrishna Gudipati 					      u32 resid_len,
4508a36c61f9SKrishna Gudipati 					      struct fchs_s *rsp_fchs);
4509a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
4510a36c61f9SKrishna Gudipati 					     struct fchs_s *rx_fchs);
4511a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_timeout(void *arg);
4512a36c61f9SKrishna Gudipati 
45135fbe25c7SJing Huang /*
4514a36c61f9SKrishna Gudipati  *  fcs_scm_sm FCS SCN state machine
4515a36c61f9SKrishna Gudipati  */
4516a36c61f9SKrishna Gudipati 
45175fbe25c7SJing Huang /*
4518a36c61f9SKrishna Gudipati  * VPort SCN State Machine events
4519a36c61f9SKrishna Gudipati  */
4520a36c61f9SKrishna Gudipati enum port_scn_event {
4521a36c61f9SKrishna Gudipati 	SCNSM_EVENT_PORT_ONLINE = 1,
4522a36c61f9SKrishna Gudipati 	SCNSM_EVENT_PORT_OFFLINE = 2,
4523a36c61f9SKrishna Gudipati 	SCNSM_EVENT_RSP_OK = 3,
4524a36c61f9SKrishna Gudipati 	SCNSM_EVENT_RSP_ERROR = 4,
4525a36c61f9SKrishna Gudipati 	SCNSM_EVENT_TIMEOUT = 5,
4526a36c61f9SKrishna Gudipati 	SCNSM_EVENT_SCR_SENT = 6,
4527a36c61f9SKrishna Gudipati };
4528a36c61f9SKrishna Gudipati 
4529a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
4530a36c61f9SKrishna Gudipati 					    enum port_scn_event event);
4531a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_sending_scr(
4532a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_scn_s *scn,
4533a36c61f9SKrishna Gudipati 					enum port_scn_event event);
4534a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
4535a36c61f9SKrishna Gudipati 					enum port_scn_event event);
4536a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
4537a36c61f9SKrishna Gudipati 					      enum port_scn_event event);
4538a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
4539a36c61f9SKrishna Gudipati 					   enum port_scn_event event);
4540a36c61f9SKrishna Gudipati 
45415fbe25c7SJing Huang /*
4542a36c61f9SKrishna Gudipati  *	Starting state - awaiting link up.
4543a36c61f9SKrishna Gudipati  */
4544a36c61f9SKrishna Gudipati static void
4545a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
4546a36c61f9SKrishna Gudipati 			enum port_scn_event event)
4547a36c61f9SKrishna Gudipati {
4548a36c61f9SKrishna Gudipati 	switch (event) {
4549a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_ONLINE:
4550a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
4551a36c61f9SKrishna Gudipati 		bfa_fcs_lport_scn_send_scr(scn, NULL);
4552a36c61f9SKrishna Gudipati 		break;
4553a36c61f9SKrishna Gudipati 
4554a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
4555a36c61f9SKrishna Gudipati 		break;
4556a36c61f9SKrishna Gudipati 
4557a36c61f9SKrishna Gudipati 	default:
4558a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
4559a36c61f9SKrishna Gudipati 	}
4560a36c61f9SKrishna Gudipati }
4561a36c61f9SKrishna Gudipati 
4562a36c61f9SKrishna Gudipati static void
4563a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn,
4564a36c61f9SKrishna Gudipati 				enum port_scn_event event)
4565a36c61f9SKrishna Gudipati {
4566a36c61f9SKrishna Gudipati 	switch (event) {
4567a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_SCR_SENT:
4568a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr);
4569a36c61f9SKrishna Gudipati 		break;
4570a36c61f9SKrishna Gudipati 
4571a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
4572a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4573a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe);
4574a36c61f9SKrishna Gudipati 		break;
4575a36c61f9SKrishna Gudipati 
4576a36c61f9SKrishna Gudipati 	default:
4577a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
4578a36c61f9SKrishna Gudipati 	}
4579a36c61f9SKrishna Gudipati }
4580a36c61f9SKrishna Gudipati 
4581a36c61f9SKrishna Gudipati static void
4582a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
4583a36c61f9SKrishna Gudipati 			enum port_scn_event event)
4584a36c61f9SKrishna Gudipati {
4585a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = scn->port;
4586a36c61f9SKrishna Gudipati 
4587a36c61f9SKrishna Gudipati 	switch (event) {
4588a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_RSP_OK:
4589a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online);
4590a36c61f9SKrishna Gudipati 		break;
4591a36c61f9SKrishna Gudipati 
4592a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_RSP_ERROR:
4593a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry);
4594a36c61f9SKrishna Gudipati 		bfa_timer_start(port->fcs->bfa, &scn->timer,
4595a36c61f9SKrishna Gudipati 				    bfa_fcs_lport_scn_timeout, scn,
4596a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
4597a36c61f9SKrishna Gudipati 		break;
4598a36c61f9SKrishna Gudipati 
4599a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
4600a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4601a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(scn->fcxp);
4602a36c61f9SKrishna Gudipati 		break;
4603a36c61f9SKrishna Gudipati 
4604a36c61f9SKrishna Gudipati 	default:
4605a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
4606a36c61f9SKrishna Gudipati 	}
4607a36c61f9SKrishna Gudipati }
4608a36c61f9SKrishna Gudipati 
4609a36c61f9SKrishna Gudipati static void
4610a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
4611a36c61f9SKrishna Gudipati 				enum port_scn_event event)
4612a36c61f9SKrishna Gudipati {
4613a36c61f9SKrishna Gudipati 	switch (event) {
4614a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_TIMEOUT:
4615a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
4616a36c61f9SKrishna Gudipati 		bfa_fcs_lport_scn_send_scr(scn, NULL);
4617a36c61f9SKrishna Gudipati 		break;
4618a36c61f9SKrishna Gudipati 
4619a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
4620a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4621a36c61f9SKrishna Gudipati 		bfa_timer_stop(&scn->timer);
4622a36c61f9SKrishna Gudipati 		break;
4623a36c61f9SKrishna Gudipati 
4624a36c61f9SKrishna Gudipati 	default:
4625a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
4626a36c61f9SKrishna Gudipati 	}
4627a36c61f9SKrishna Gudipati }
4628a36c61f9SKrishna Gudipati 
4629a36c61f9SKrishna Gudipati static void
4630a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
4631a36c61f9SKrishna Gudipati 			enum port_scn_event event)
4632a36c61f9SKrishna Gudipati {
4633a36c61f9SKrishna Gudipati 	switch (event) {
4634a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
4635a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4636a36c61f9SKrishna Gudipati 		break;
4637a36c61f9SKrishna Gudipati 
4638a36c61f9SKrishna Gudipati 	default:
4639a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
4640a36c61f9SKrishna Gudipati 	}
4641a36c61f9SKrishna Gudipati }
4642a36c61f9SKrishna Gudipati 
4643a36c61f9SKrishna Gudipati 
4644a36c61f9SKrishna Gudipati 
46455fbe25c7SJing Huang /*
4646a36c61f9SKrishna Gudipati  *  fcs_scn_private FCS SCN private functions
4647a36c61f9SKrishna Gudipati  */
4648a36c61f9SKrishna Gudipati 
46495fbe25c7SJing Huang /*
4650a36c61f9SKrishna Gudipati  * This routine will be called to send a SCR command.
4651a36c61f9SKrishna Gudipati  */
4652a36c61f9SKrishna Gudipati static void
4653a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4654a36c61f9SKrishna Gudipati {
4655a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = scn_cbarg;
4656a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = scn->port;
4657a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4658a36c61f9SKrishna Gudipati 	int             len;
4659a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4660a36c61f9SKrishna Gudipati 
4661a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
4662a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4663a36c61f9SKrishna Gudipati 
4664c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4665c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4666a36c61f9SKrishna Gudipati 	if (!fcxp) {
4667a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
4668c3f1b123SKrishna Gudipati 				bfa_fcs_lport_scn_send_scr, scn, BFA_TRUE);
4669a36c61f9SKrishna Gudipati 		return;
4670a36c61f9SKrishna Gudipati 	}
4671a36c61f9SKrishna Gudipati 	scn->fcxp = fcxp;
4672a36c61f9SKrishna Gudipati 
4673a36c61f9SKrishna Gudipati 	/* Handle VU registrations for Base port only */
4674a36c61f9SKrishna Gudipati 	if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
4675a36c61f9SKrishna Gudipati 		len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4676f7f73812SMaggie Zhang 				port->fabric->lps->brcd_switch,
4677a36c61f9SKrishna Gudipati 				port->pid, 0);
4678a36c61f9SKrishna Gudipati 	} else {
4679a36c61f9SKrishna Gudipati 	    len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4680a36c61f9SKrishna Gudipati 				    BFA_FALSE,
4681a36c61f9SKrishna Gudipati 				    port->pid, 0);
4682a36c61f9SKrishna Gudipati 	}
4683a36c61f9SKrishna Gudipati 
4684a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4685a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4686a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_scn_scr_response,
4687a36c61f9SKrishna Gudipati 			  (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV);
4688a36c61f9SKrishna Gudipati 
4689a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT);
4690a36c61f9SKrishna Gudipati }
4691a36c61f9SKrishna Gudipati 
4692a36c61f9SKrishna Gudipati static void
4693a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4694a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
4695a36c61f9SKrishna Gudipati 			      u32 resid_len, struct fchs_s *rsp_fchs)
4696a36c61f9SKrishna Gudipati {
4697a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg;
4698a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = scn->port;
4699a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd;
4700a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
4701a36c61f9SKrishna Gudipati 
4702a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4703a36c61f9SKrishna Gudipati 
4704a36c61f9SKrishna Gudipati 	/*
4705a36c61f9SKrishna Gudipati 	 * Sanity Checks
4706a36c61f9SKrishna Gudipati 	 */
4707a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4708a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4709a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4710a36c61f9SKrishna Gudipati 		return;
4711a36c61f9SKrishna Gudipati 	}
4712a36c61f9SKrishna Gudipati 
4713a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
4714a36c61f9SKrishna Gudipati 
4715a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
4716a36c61f9SKrishna Gudipati 
4717a36c61f9SKrishna Gudipati 	case FC_ELS_ACC:
4718a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK);
4719a36c61f9SKrishna Gudipati 		break;
4720a36c61f9SKrishna Gudipati 
4721a36c61f9SKrishna Gudipati 	case FC_ELS_LS_RJT:
4722a36c61f9SKrishna Gudipati 
4723a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
4724a36c61f9SKrishna Gudipati 
4725a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code);
4726a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code_expl);
4727a36c61f9SKrishna Gudipati 
4728a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4729a36c61f9SKrishna Gudipati 		break;
4730a36c61f9SKrishna Gudipati 
4731a36c61f9SKrishna Gudipati 	default:
4732a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
4733a36c61f9SKrishna Gudipati 	}
4734a36c61f9SKrishna Gudipati }
4735a36c61f9SKrishna Gudipati 
4736a36c61f9SKrishna Gudipati /*
4737a36c61f9SKrishna Gudipati  * Send a LS Accept
4738a36c61f9SKrishna Gudipati  */
4739a36c61f9SKrishna Gudipati static void
4740a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
4741a36c61f9SKrishna Gudipati 				struct fchs_s *rx_fchs)
4742a36c61f9SKrishna Gudipati {
4743a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4744a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4745a36c61f9SKrishna Gudipati 	struct bfa_rport_s *bfa_rport = NULL;
4746a36c61f9SKrishna Gudipati 	int             len;
4747a36c61f9SKrishna Gudipati 
4748a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
4749a36c61f9SKrishna Gudipati 
4750c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
4751a36c61f9SKrishna Gudipati 	if (!fcxp)
4752a36c61f9SKrishna Gudipati 		return;
4753a36c61f9SKrishna Gudipati 
4754a36c61f9SKrishna Gudipati 	len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4755a36c61f9SKrishna Gudipati 			      rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
4756a36c61f9SKrishna Gudipati 			      rx_fchs->ox_id);
4757a36c61f9SKrishna Gudipati 
4758a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
4759a36c61f9SKrishna Gudipati 			  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
4760a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, 0);
4761a36c61f9SKrishna Gudipati }
4762a36c61f9SKrishna Gudipati 
47635fbe25c7SJing Huang /*
4764a36c61f9SKrishna Gudipati  *     This routine will be called by bfa_timer on timer timeouts.
4765a36c61f9SKrishna Gudipati  *
4766a36c61f9SKrishna Gudipati  *	param[in]	vport		- pointer to bfa_fcs_lport_t.
4767a36c61f9SKrishna Gudipati  *	param[out]	vport_status	- pointer to return vport status in
4768a36c61f9SKrishna Gudipati  *
4769a36c61f9SKrishna Gudipati  *	return
4770a36c61f9SKrishna Gudipati  *		void
4771a36c61f9SKrishna Gudipati  *
4772a36c61f9SKrishna Gudipati  *	Special Considerations:
4773a36c61f9SKrishna Gudipati  *
4774a36c61f9SKrishna Gudipati  *	note
4775a36c61f9SKrishna Gudipati  */
4776a36c61f9SKrishna Gudipati static void
4777a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout(void *arg)
4778a36c61f9SKrishna Gudipati {
4779a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg;
4780a36c61f9SKrishna Gudipati 
4781a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT);
4782a36c61f9SKrishna Gudipati }
4783a36c61f9SKrishna Gudipati 
4784a36c61f9SKrishna Gudipati 
4785a36c61f9SKrishna Gudipati 
47865fbe25c7SJing Huang /*
4787a36c61f9SKrishna Gudipati  *  fcs_scn_public FCS state change notification public interfaces
4788a36c61f9SKrishna Gudipati  */
4789a36c61f9SKrishna Gudipati 
4790a36c61f9SKrishna Gudipati /*
4791a36c61f9SKrishna Gudipati  * Functions called by port/fab
4792a36c61f9SKrishna Gudipati  */
4793a36c61f9SKrishna Gudipati void
4794a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port)
4795a36c61f9SKrishna Gudipati {
4796a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4797a36c61f9SKrishna Gudipati 
4798a36c61f9SKrishna Gudipati 	scn->port = port;
4799a36c61f9SKrishna Gudipati 	bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
4800a36c61f9SKrishna Gudipati }
4801a36c61f9SKrishna Gudipati 
4802a36c61f9SKrishna Gudipati void
4803a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port)
4804a36c61f9SKrishna Gudipati {
4805a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4806a36c61f9SKrishna Gudipati 
4807a36c61f9SKrishna Gudipati 	scn->port = port;
4808a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE);
4809a36c61f9SKrishna Gudipati }
4810a36c61f9SKrishna Gudipati 
4811a36c61f9SKrishna Gudipati void
4812a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port)
4813a36c61f9SKrishna Gudipati {
4814a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
4815a36c61f9SKrishna Gudipati 
4816a36c61f9SKrishna Gudipati 	scn->port = port;
4817a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE);
4818a36c61f9SKrishna Gudipati }
4819a36c61f9SKrishna Gudipati 
4820a36c61f9SKrishna Gudipati static void
4821a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
4822a36c61f9SKrishna Gudipati {
4823a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
4824a36c61f9SKrishna Gudipati 
4825a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpid);
4826a36c61f9SKrishna Gudipati 
48275fbe25c7SJing Huang 	/*
4828a36c61f9SKrishna Gudipati 	 * If this is an unknown device, then it just came online.
4829a36c61f9SKrishna Gudipati 	 * Otherwise let rport handle the RSCN event.
4830a36c61f9SKrishna Gudipati 	 */
4831a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pid(port, rpid);
4832ee1a4a42SKrishna Gudipati 	if (!rport)
4833ee1a4a42SKrishna Gudipati 		rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid);
4834ee1a4a42SKrishna Gudipati 
4835a36c61f9SKrishna Gudipati 	if (rport == NULL) {
4836a36c61f9SKrishna Gudipati 		/*
4837a36c61f9SKrishna Gudipati 		 * If min cfg mode is enabled, we donot need to
4838a36c61f9SKrishna Gudipati 		 * discover any new rports.
4839a36c61f9SKrishna Gudipati 		 */
4840a36c61f9SKrishna Gudipati 		if (!__fcs_min_cfg(port->fcs))
4841a36c61f9SKrishna Gudipati 			rport = bfa_fcs_rport_create(port, rpid);
4842a36c61f9SKrishna Gudipati 	} else
4843a36c61f9SKrishna Gudipati 		bfa_fcs_rport_scn(rport);
4844a36c61f9SKrishna Gudipati }
4845a36c61f9SKrishna Gudipati 
48465fbe25c7SJing Huang /*
4847a36c61f9SKrishna Gudipati  * rscn format based PID comparison
4848a36c61f9SKrishna Gudipati  */
4849a36c61f9SKrishna Gudipati #define __fc_pid_match(__c0, __c1, __fmt)		\
4850a36c61f9SKrishna Gudipati 	(((__fmt) == FC_RSCN_FORMAT_FABRIC) ||		\
4851a36c61f9SKrishna Gudipati 	 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) &&		\
4852a36c61f9SKrishna Gudipati 	  ((__c0)[0] == (__c1)[0])) ||				\
4853a36c61f9SKrishna Gudipati 	 (((__fmt) == FC_RSCN_FORMAT_AREA) &&		\
4854a36c61f9SKrishna Gudipati 	  ((__c0)[0] == (__c1)[0]) &&				\
4855a36c61f9SKrishna Gudipati 	  ((__c0)[1] == (__c1)[1])))
4856a36c61f9SKrishna Gudipati 
4857a36c61f9SKrishna Gudipati static void
4858a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port,
4859a36c61f9SKrishna Gudipati 				enum fc_rscn_format format,
4860a36c61f9SKrishna Gudipati 				u32 rscn_pid)
4861a36c61f9SKrishna Gudipati {
4862a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
4863a36c61f9SKrishna Gudipati 	struct list_head        *qe, *qe_next;
4864a36c61f9SKrishna Gudipati 	u8        *c0, *c1;
4865a36c61f9SKrishna Gudipati 
4866a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, format);
4867a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rscn_pid);
4868a36c61f9SKrishna Gudipati 
4869a36c61f9SKrishna Gudipati 	c0 = (u8 *) &rscn_pid;
4870a36c61f9SKrishna Gudipati 
4871a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qe_next, &port->rport_q) {
4872a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
4873a36c61f9SKrishna Gudipati 		c1 = (u8 *) &rport->pid;
4874a36c61f9SKrishna Gudipati 		if (__fc_pid_match(c0, c1, format))
4875a36c61f9SKrishna Gudipati 			bfa_fcs_rport_scn(rport);
4876a36c61f9SKrishna Gudipati 	}
4877a36c61f9SKrishna Gudipati }
4878a36c61f9SKrishna Gudipati 
4879a36c61f9SKrishna Gudipati 
4880a36c61f9SKrishna Gudipati void
4881a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
4882a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u32 len)
4883a36c61f9SKrishna Gudipati {
4884a36c61f9SKrishna Gudipati 	struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1);
4885a36c61f9SKrishna Gudipati 	int             num_entries;
4886a36c61f9SKrishna Gudipati 	u32        rscn_pid;
4887a36c61f9SKrishna Gudipati 	bfa_boolean_t   nsquery = BFA_FALSE, found;
4888a36c61f9SKrishna Gudipati 	int             i = 0, j;
4889a36c61f9SKrishna Gudipati 
4890a36c61f9SKrishna Gudipati 	num_entries =
4891ba816ea8SJing Huang 		(be16_to_cpu(rscn->payldlen) -
4892a36c61f9SKrishna Gudipati 		 sizeof(u32)) / sizeof(rscn->event[0]);
4893a36c61f9SKrishna Gudipati 
4894a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, num_entries);
4895a36c61f9SKrishna Gudipati 
4896a36c61f9SKrishna Gudipati 	port->stats.num_rscn++;
4897a36c61f9SKrishna Gudipati 
4898a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_send_ls_acc(port, fchs);
4899a36c61f9SKrishna Gudipati 
4900a36c61f9SKrishna Gudipati 	for (i = 0; i < num_entries; i++) {
4901a36c61f9SKrishna Gudipati 		rscn_pid = rscn->event[i].portid;
4902a36c61f9SKrishna Gudipati 
4903a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rscn->event[i].format);
4904a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rscn_pid);
4905a36c61f9SKrishna Gudipati 
4906a36c61f9SKrishna Gudipati 		/* check for duplicate entries in the list */
4907a36c61f9SKrishna Gudipati 		found = BFA_FALSE;
4908a36c61f9SKrishna Gudipati 		for (j = 0; j < i; j++) {
4909a36c61f9SKrishna Gudipati 			if (rscn->event[j].portid == rscn_pid) {
4910a36c61f9SKrishna Gudipati 				found = BFA_TRUE;
4911a36c61f9SKrishna Gudipati 				break;
4912a36c61f9SKrishna Gudipati 			}
4913a36c61f9SKrishna Gudipati 		}
4914a36c61f9SKrishna Gudipati 
4915a36c61f9SKrishna Gudipati 		/* if found in down the list, pid has been already processed */
4916a36c61f9SKrishna Gudipati 		if (found) {
4917a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rscn_pid);
4918a36c61f9SKrishna Gudipati 			continue;
4919a36c61f9SKrishna Gudipati 		}
4920a36c61f9SKrishna Gudipati 
4921a36c61f9SKrishna Gudipati 		switch (rscn->event[i].format) {
4922a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_PORTID:
4923a36c61f9SKrishna Gudipati 			if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) {
4924a36c61f9SKrishna Gudipati 				/*
4925a36c61f9SKrishna Gudipati 				 * Ignore this event.
4926a36c61f9SKrishna Gudipati 				 * f/w would have processed it
4927a36c61f9SKrishna Gudipati 				 */
4928a36c61f9SKrishna Gudipati 				bfa_trc(port->fcs, rscn_pid);
4929a36c61f9SKrishna Gudipati 			} else {
4930a36c61f9SKrishna Gudipati 				port->stats.num_portid_rscn++;
4931a36c61f9SKrishna Gudipati 				bfa_fcs_lport_scn_portid_rscn(port, rscn_pid);
4932a36c61f9SKrishna Gudipati 			}
4933a36c61f9SKrishna Gudipati 		break;
4934a36c61f9SKrishna Gudipati 
4935a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_FABRIC:
4936a36c61f9SKrishna Gudipati 			if (rscn->event[i].qualifier ==
4937a36c61f9SKrishna Gudipati 					FC_FABRIC_NAME_RSCN_EVENT) {
4938a36c61f9SKrishna Gudipati 				bfa_fcs_lport_ms_fabric_rscn(port);
4939a36c61f9SKrishna Gudipati 				break;
4940a36c61f9SKrishna Gudipati 			}
4941a36c61f9SKrishna Gudipati 			/* !!!!!!!!! Fall Through !!!!!!!!!!!!! */
4942a36c61f9SKrishna Gudipati 
4943a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_AREA:
4944a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_DOMAIN:
4945a36c61f9SKrishna Gudipati 			nsquery = BFA_TRUE;
4946a36c61f9SKrishna Gudipati 			bfa_fcs_lport_scn_multiport_rscn(port,
4947a36c61f9SKrishna Gudipati 							rscn->event[i].format,
4948a36c61f9SKrishna Gudipati 							rscn_pid);
4949a36c61f9SKrishna Gudipati 			break;
4950a36c61f9SKrishna Gudipati 
4951a36c61f9SKrishna Gudipati 
4952a36c61f9SKrishna Gudipati 		default:
4953d4b671c5SJing Huang 			WARN_ON(1);
4954a36c61f9SKrishna Gudipati 			nsquery = BFA_TRUE;
4955a36c61f9SKrishna Gudipati 		}
4956a36c61f9SKrishna Gudipati 	}
4957a36c61f9SKrishna Gudipati 
49585fbe25c7SJing Huang 	/*
49595fbe25c7SJing Huang 	 * If any of area, domain or fabric RSCN is received, do a fresh
49605fbe25c7SJing Huang 	 * discovery to find new devices.
4961a36c61f9SKrishna Gudipati 	 */
4962a36c61f9SKrishna Gudipati 	if (nsquery)
4963a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_query(port);
4964a36c61f9SKrishna Gudipati }
4965a36c61f9SKrishna Gudipati 
49665fbe25c7SJing Huang /*
4967a36c61f9SKrishna Gudipati  * BFA FCS port
4968a36c61f9SKrishna Gudipati  */
49695fbe25c7SJing Huang /*
4970a36c61f9SKrishna Gudipati  *  fcs_port_api BFA FCS port API
4971a36c61f9SKrishna Gudipati  */
4972a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *
4973a36c61f9SKrishna Gudipati bfa_fcs_get_base_port(struct bfa_fcs_s *fcs)
4974a36c61f9SKrishna Gudipati {
4975a36c61f9SKrishna Gudipati 	return &fcs->fabric.bport;
4976a36c61f9SKrishna Gudipati }
4977a36c61f9SKrishna Gudipati 
4978a36c61f9SKrishna Gudipati wwn_t
4979a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index,
4980a36c61f9SKrishna Gudipati 		int nrports, bfa_boolean_t bwwn)
4981a36c61f9SKrishna Gudipati {
4982a36c61f9SKrishna Gudipati 	struct list_head	*qh, *qe;
4983a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = NULL;
4984a36c61f9SKrishna Gudipati 	int	i;
4985a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs;
4986a36c61f9SKrishna Gudipati 
4987a36c61f9SKrishna Gudipati 	if (port == NULL || nrports == 0)
4988a36c61f9SKrishna Gudipati 		return (wwn_t) 0;
4989a36c61f9SKrishna Gudipati 
4990a36c61f9SKrishna Gudipati 	fcs = port->fcs;
4991a36c61f9SKrishna Gudipati 	bfa_trc(fcs, (u32) nrports);
4992a36c61f9SKrishna Gudipati 
4993a36c61f9SKrishna Gudipati 	i = 0;
4994a36c61f9SKrishna Gudipati 	qh = &port->rport_q;
4995a36c61f9SKrishna Gudipati 	qe = bfa_q_first(qh);
4996a36c61f9SKrishna Gudipati 
4997a36c61f9SKrishna Gudipati 	while ((qe != qh) && (i < nrports)) {
4998a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
4999f16a1750SMaggie Zhang 		if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
5000a36c61f9SKrishna Gudipati 			qe = bfa_q_next(qe);
5001a36c61f9SKrishna Gudipati 			bfa_trc(fcs, (u32) rport->pwwn);
5002a36c61f9SKrishna Gudipati 			bfa_trc(fcs, rport->pid);
5003a36c61f9SKrishna Gudipati 			bfa_trc(fcs, i);
5004a36c61f9SKrishna Gudipati 			continue;
5005a36c61f9SKrishna Gudipati 		}
5006a36c61f9SKrishna Gudipati 
5007a36c61f9SKrishna Gudipati 		if (bwwn) {
5008a36c61f9SKrishna Gudipati 			if (!memcmp(&wwn, &rport->pwwn, 8))
5009a36c61f9SKrishna Gudipati 				break;
5010a36c61f9SKrishna Gudipati 		} else {
5011a36c61f9SKrishna Gudipati 			if (i == index)
5012a36c61f9SKrishna Gudipati 				break;
5013a36c61f9SKrishna Gudipati 		}
5014a36c61f9SKrishna Gudipati 
5015a36c61f9SKrishna Gudipati 		i++;
5016a36c61f9SKrishna Gudipati 		qe = bfa_q_next(qe);
5017a36c61f9SKrishna Gudipati 	}
5018a36c61f9SKrishna Gudipati 
5019a36c61f9SKrishna Gudipati 	bfa_trc(fcs, i);
5020a36c61f9SKrishna Gudipati 	if (rport)
5021a36c61f9SKrishna Gudipati 		return rport->pwwn;
5022a36c61f9SKrishna Gudipati 	else
5023a36c61f9SKrishna Gudipati 		return (wwn_t) 0;
5024a36c61f9SKrishna Gudipati }
5025a36c61f9SKrishna Gudipati 
5026a36c61f9SKrishna Gudipati void
5027ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
5028ee1a4a42SKrishna Gudipati 		struct bfa_rport_qualifier_s rports[], int *nrports)
5029a36c61f9SKrishna Gudipati {
5030a36c61f9SKrishna Gudipati 	struct list_head	*qh, *qe;
5031a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = NULL;
5032a36c61f9SKrishna Gudipati 	int	i;
5033a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs;
5034a36c61f9SKrishna Gudipati 
5035ee1a4a42SKrishna Gudipati 	if (port == NULL || rports == NULL || *nrports == 0)
5036a36c61f9SKrishna Gudipati 		return;
5037a36c61f9SKrishna Gudipati 
5038a36c61f9SKrishna Gudipati 	fcs = port->fcs;
5039a36c61f9SKrishna Gudipati 	bfa_trc(fcs, (u32) *nrports);
5040a36c61f9SKrishna Gudipati 
5041a36c61f9SKrishna Gudipati 	i = 0;
5042a36c61f9SKrishna Gudipati 	qh = &port->rport_q;
5043a36c61f9SKrishna Gudipati 	qe = bfa_q_first(qh);
5044a36c61f9SKrishna Gudipati 
5045a36c61f9SKrishna Gudipati 	while ((qe != qh) && (i < *nrports)) {
5046a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
5047f16a1750SMaggie Zhang 		if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
5048a36c61f9SKrishna Gudipati 			qe = bfa_q_next(qe);
5049a36c61f9SKrishna Gudipati 			bfa_trc(fcs, (u32) rport->pwwn);
5050a36c61f9SKrishna Gudipati 			bfa_trc(fcs, rport->pid);
5051a36c61f9SKrishna Gudipati 			bfa_trc(fcs, i);
5052a36c61f9SKrishna Gudipati 			continue;
5053a36c61f9SKrishna Gudipati 		}
5054a36c61f9SKrishna Gudipati 
5055ee1a4a42SKrishna Gudipati 		if (!rport->pwwn && !rport->pid) {
5056ee1a4a42SKrishna Gudipati 			qe = bfa_q_next(qe);
5057ee1a4a42SKrishna Gudipati 			continue;
5058ee1a4a42SKrishna Gudipati 		}
5059ee1a4a42SKrishna Gudipati 
5060ee1a4a42SKrishna Gudipati 		rports[i].pwwn = rport->pwwn;
5061ee1a4a42SKrishna Gudipati 		rports[i].pid = rport->pid;
5062a36c61f9SKrishna Gudipati 
5063a36c61f9SKrishna Gudipati 		i++;
5064a36c61f9SKrishna Gudipati 		qe = bfa_q_next(qe);
5065a36c61f9SKrishna Gudipati 	}
5066a36c61f9SKrishna Gudipati 
5067a36c61f9SKrishna Gudipati 	bfa_trc(fcs, i);
5068a36c61f9SKrishna Gudipati 	*nrports = i;
5069a36c61f9SKrishna Gudipati }
5070a36c61f9SKrishna Gudipati 
5071a36c61f9SKrishna Gudipati /*
5072a36c61f9SKrishna Gudipati  * Iterate's through all the rport's in the given port to
5073a36c61f9SKrishna Gudipati  * determine the maximum operating speed.
5074a36c61f9SKrishna Gudipati  *
5075a36c61f9SKrishna Gudipati  * !!!! To be used in TRL Functionality only !!!!
5076a36c61f9SKrishna Gudipati  */
5077a36c61f9SKrishna Gudipati bfa_port_speed_t
5078a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port)
5079a36c61f9SKrishna Gudipati {
5080a36c61f9SKrishna Gudipati 	struct list_head *qh, *qe;
5081a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = NULL;
5082a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs;
5083a36c61f9SKrishna Gudipati 	bfa_port_speed_t max_speed = 0;
5084a36c61f9SKrishna Gudipati 	struct bfa_port_attr_s port_attr;
5085a36c61f9SKrishna Gudipati 	bfa_port_speed_t port_speed, rport_speed;
5086a36c61f9SKrishna Gudipati 	bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa);
5087a36c61f9SKrishna Gudipati 
5088a36c61f9SKrishna Gudipati 
5089a36c61f9SKrishna Gudipati 	if (port == NULL)
5090a36c61f9SKrishna Gudipati 		return 0;
5091a36c61f9SKrishna Gudipati 
5092a36c61f9SKrishna Gudipati 	fcs = port->fcs;
5093a36c61f9SKrishna Gudipati 
5094a36c61f9SKrishna Gudipati 	/* Get Physical port's current speed */
5095a36c61f9SKrishna Gudipati 	bfa_fcport_get_attr(port->fcs->bfa, &port_attr);
5096a36c61f9SKrishna Gudipati 	port_speed = port_attr.speed;
5097a36c61f9SKrishna Gudipati 	bfa_trc(fcs, port_speed);
5098a36c61f9SKrishna Gudipati 
5099a36c61f9SKrishna Gudipati 	qh = &port->rport_q;
5100a36c61f9SKrishna Gudipati 	qe = bfa_q_first(qh);
5101a36c61f9SKrishna Gudipati 
5102a36c61f9SKrishna Gudipati 	while (qe != qh) {
5103a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
5104f16a1750SMaggie Zhang 		if ((bfa_ntoh3b(rport->pid) > 0xFFF000) ||
5105d7be54ccSKrishna Gudipati 			(bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) ||
5106d7be54ccSKrishna Gudipati 			(rport->scsi_function != BFA_RPORT_TARGET)) {
5107a36c61f9SKrishna Gudipati 			qe = bfa_q_next(qe);
5108a36c61f9SKrishna Gudipati 			continue;
5109a36c61f9SKrishna Gudipati 		}
5110a36c61f9SKrishna Gudipati 
5111a36c61f9SKrishna Gudipati 		rport_speed = rport->rpf.rpsc_speed;
5112a36c61f9SKrishna Gudipati 		if ((trl_enabled) && (rport_speed ==
5113a36c61f9SKrishna Gudipati 			BFA_PORT_SPEED_UNKNOWN)) {
5114a36c61f9SKrishna Gudipati 			/* Use default ratelim speed setting */
5115a36c61f9SKrishna Gudipati 			rport_speed =
5116a36c61f9SKrishna Gudipati 				bfa_fcport_get_ratelim_speed(port->fcs->bfa);
5117a36c61f9SKrishna Gudipati 		}
5118a36c61f9SKrishna Gudipati 
5119d7be54ccSKrishna Gudipati 		if (rport_speed > max_speed)
5120a36c61f9SKrishna Gudipati 			max_speed = rport_speed;
5121a36c61f9SKrishna Gudipati 
5122a36c61f9SKrishna Gudipati 		qe = bfa_q_next(qe);
5123a36c61f9SKrishna Gudipati 	}
5124a36c61f9SKrishna Gudipati 
5125d7be54ccSKrishna Gudipati 	if (max_speed > port_speed)
5126d7be54ccSKrishna Gudipati 		max_speed = port_speed;
5127d7be54ccSKrishna Gudipati 
5128a36c61f9SKrishna Gudipati 	bfa_trc(fcs, max_speed);
5129a36c61f9SKrishna Gudipati 	return max_speed;
5130a36c61f9SKrishna Gudipati }
5131a36c61f9SKrishna Gudipati 
5132a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *
5133a36c61f9SKrishna Gudipati bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn)
5134a36c61f9SKrishna Gudipati {
5135a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
5136a36c61f9SKrishna Gudipati 	bfa_fcs_vf_t   *vf;
5137a36c61f9SKrishna Gudipati 
5138d4b671c5SJing Huang 	WARN_ON(fcs == NULL);
5139a36c61f9SKrishna Gudipati 
5140a36c61f9SKrishna Gudipati 	vf = bfa_fcs_vf_lookup(fcs, vf_id);
5141a36c61f9SKrishna Gudipati 	if (vf == NULL) {
5142a36c61f9SKrishna Gudipati 		bfa_trc(fcs, vf_id);
5143a36c61f9SKrishna Gudipati 		return NULL;
5144a36c61f9SKrishna Gudipati 	}
5145a36c61f9SKrishna Gudipati 
5146a36c61f9SKrishna Gudipati 	if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
5147a36c61f9SKrishna Gudipati 		return &vf->bport;
5148a36c61f9SKrishna Gudipati 
5149a36c61f9SKrishna Gudipati 	vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
5150a36c61f9SKrishna Gudipati 	if (vport)
5151a36c61f9SKrishna Gudipati 		return &vport->lport;
5152a36c61f9SKrishna Gudipati 
5153a36c61f9SKrishna Gudipati 	return NULL;
5154a36c61f9SKrishna Gudipati }
5155a36c61f9SKrishna Gudipati 
5156a36c61f9SKrishna Gudipati /*
5157a36c61f9SKrishna Gudipati  *  API corresponding to NPIV_VPORT_GETINFO.
5158a36c61f9SKrishna Gudipati  */
5159a36c61f9SKrishna Gudipati void
5160a36c61f9SKrishna Gudipati bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
5161a36c61f9SKrishna Gudipati 	 struct bfa_lport_info_s *port_info)
5162a36c61f9SKrishna Gudipati {
5163a36c61f9SKrishna Gudipati 
5164a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->fabric->fabric_name);
5165a36c61f9SKrishna Gudipati 
5166a36c61f9SKrishna Gudipati 	if (port->vport == NULL) {
5167a36c61f9SKrishna Gudipati 		/*
5168a36c61f9SKrishna Gudipati 		 * This is a Physical port
5169a36c61f9SKrishna Gudipati 		 */
5170a36c61f9SKrishna Gudipati 		port_info->port_type = BFA_LPORT_TYPE_PHYSICAL;
5171a36c61f9SKrishna Gudipati 
5172a36c61f9SKrishna Gudipati 		/*
5173a36c61f9SKrishna Gudipati 		 * @todo : need to fix the state & reason
5174a36c61f9SKrishna Gudipati 		 */
5175a36c61f9SKrishna Gudipati 		port_info->port_state = 0;
5176a36c61f9SKrishna Gudipati 		port_info->offline_reason = 0;
5177a36c61f9SKrishna Gudipati 
5178a36c61f9SKrishna Gudipati 		port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5179a36c61f9SKrishna Gudipati 		port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5180a36c61f9SKrishna Gudipati 
5181a36c61f9SKrishna Gudipati 		port_info->max_vports_supp =
5182a36c61f9SKrishna Gudipati 			bfa_lps_get_max_vport(port->fcs->bfa);
5183a36c61f9SKrishna Gudipati 		port_info->num_vports_inuse =
5184f7f73812SMaggie Zhang 			port->fabric->num_vports;
5185a36c61f9SKrishna Gudipati 		port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
5186a36c61f9SKrishna Gudipati 		port_info->num_rports_inuse = port->num_rports;
5187a36c61f9SKrishna Gudipati 	} else {
5188a36c61f9SKrishna Gudipati 		/*
5189a36c61f9SKrishna Gudipati 		 * This is a virtual port
5190a36c61f9SKrishna Gudipati 		 */
5191a36c61f9SKrishna Gudipati 		port_info->port_type = BFA_LPORT_TYPE_VIRTUAL;
5192a36c61f9SKrishna Gudipati 
5193a36c61f9SKrishna Gudipati 		/*
5194a36c61f9SKrishna Gudipati 		 * @todo : need to fix the state & reason
5195a36c61f9SKrishna Gudipati 		 */
5196a36c61f9SKrishna Gudipati 		port_info->port_state = 0;
5197a36c61f9SKrishna Gudipati 		port_info->offline_reason = 0;
5198a36c61f9SKrishna Gudipati 
5199a36c61f9SKrishna Gudipati 		port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5200a36c61f9SKrishna Gudipati 		port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5201a36c61f9SKrishna Gudipati 	}
5202a36c61f9SKrishna Gudipati }
5203a36c61f9SKrishna Gudipati 
5204a36c61f9SKrishna Gudipati void
5205a36c61f9SKrishna Gudipati bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port,
5206a36c61f9SKrishna Gudipati 	 struct bfa_lport_stats_s *port_stats)
5207a36c61f9SKrishna Gudipati {
5208a36c61f9SKrishna Gudipati 	*port_stats = fcs_port->stats;
5209a36c61f9SKrishna Gudipati }
5210a36c61f9SKrishna Gudipati 
5211a36c61f9SKrishna Gudipati void
5212a36c61f9SKrishna Gudipati bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port)
5213a36c61f9SKrishna Gudipati {
52146a18b167SJing Huang 	memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s));
5215a36c61f9SKrishna Gudipati }
5216a36c61f9SKrishna Gudipati 
52175fbe25c7SJing Huang /*
5218a36c61f9SKrishna Gudipati  * FCS virtual port state machine
5219a36c61f9SKrishna Gudipati  */
5220a36c61f9SKrishna Gudipati 
5221a36c61f9SKrishna Gudipati #define __vport_fcs(__vp)       ((__vp)->lport.fcs)
5222a36c61f9SKrishna Gudipati #define __vport_pwwn(__vp)      ((__vp)->lport.port_cfg.pwwn)
5223a36c61f9SKrishna Gudipati #define __vport_nwwn(__vp)      ((__vp)->lport.port_cfg.nwwn)
5224a36c61f9SKrishna Gudipati #define __vport_bfa(__vp)       ((__vp)->lport.fcs->bfa)
5225a36c61f9SKrishna Gudipati #define __vport_fcid(__vp)      ((__vp)->lport.pid)
5226a36c61f9SKrishna Gudipati #define __vport_fabric(__vp)    ((__vp)->lport.fabric)
5227a36c61f9SKrishna Gudipati #define __vport_vfid(__vp)      ((__vp)->lport.fabric->vf_id)
5228a36c61f9SKrishna Gudipati 
5229a36c61f9SKrishna Gudipati #define BFA_FCS_VPORT_MAX_RETRIES  5
5230a36c61f9SKrishna Gudipati /*
5231a36c61f9SKrishna Gudipati  * Forward declarations
5232a36c61f9SKrishna Gudipati  */
5233a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport);
5234a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_timeout(void *vport_arg);
5235a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport);
5236a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport);
5237a36c61f9SKrishna Gudipati 
52385fbe25c7SJing Huang /*
5239a36c61f9SKrishna Gudipati  *  fcs_vport_sm FCS virtual port state machine
5240a36c61f9SKrishna Gudipati  */
5241a36c61f9SKrishna Gudipati 
52425fbe25c7SJing Huang /*
5243a36c61f9SKrishna Gudipati  * VPort State Machine events
5244a36c61f9SKrishna Gudipati  */
5245a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event {
5246a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_CREATE = 1,	/*  vport create event */
5247a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_DELETE = 2,	/*  vport delete event */
5248a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_START = 3,	/*  vport start request */
5249a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_STOP = 4,	/*  stop: unsupported */
5250a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_ONLINE = 5,	/*  fabric online */
5251a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_OFFLINE = 6,	/*  fabric offline event */
5252a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_FRMSENT = 7,	/*  fdisc/logo sent events */
5253a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_OK = 8,	/*  good response */
5254a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_ERROR = 9,	/*  error/bad response */
5255a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_TIMEOUT = 10,	/*  delay timer event */
5256a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_DELCOMP = 11,	/*  lport delete completion */
5257a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12,	/*  Dup wnn error*/
5258a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_FAILED = 13,	/*  non-retryable failure */
5259dd5aaf45SKrishna Gudipati 	BFA_FCS_VPORT_SM_STOPCOMP = 14,	/* vport delete completion */
5260a36c61f9SKrishna Gudipati };
5261a36c61f9SKrishna Gudipati 
5262a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
5263a36c61f9SKrishna Gudipati 					enum bfa_fcs_vport_event event);
5264a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
5265a36c61f9SKrishna Gudipati 					 enum bfa_fcs_vport_event event);
5266a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
5267a36c61f9SKrishna Gudipati 					 enum bfa_fcs_vport_event event);
5268a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
5269a36c61f9SKrishna Gudipati 				       enum bfa_fcs_vport_event event);
5270a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
5271a36c61f9SKrishna Gudipati 					     enum bfa_fcs_vport_event event);
5272d7be54ccSKrishna Gudipati static void	bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
5273d7be54ccSKrishna Gudipati 					enum bfa_fcs_vport_event event);
5274a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
5275a36c61f9SKrishna Gudipati 					enum bfa_fcs_vport_event event);
5276a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
5277a36c61f9SKrishna Gudipati 					  enum bfa_fcs_vport_event event);
5278a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
5279a36c61f9SKrishna Gudipati 					 enum bfa_fcs_vport_event event);
5280a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
5281a36c61f9SKrishna Gudipati 				      enum bfa_fcs_vport_event event);
5282a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
5283a36c61f9SKrishna Gudipati 				      enum bfa_fcs_vport_event event);
5284dd5aaf45SKrishna Gudipati static void	bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
5285dd5aaf45SKrishna Gudipati 					enum bfa_fcs_vport_event event);
5286dd5aaf45SKrishna Gudipati static void	bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
5287dd5aaf45SKrishna Gudipati 					enum bfa_fcs_vport_event event);
5288a36c61f9SKrishna Gudipati 
5289a36c61f9SKrishna Gudipati static struct bfa_sm_table_s  vport_sm_table[] = {
5290a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT},
5291a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED},
5292a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE},
5293a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC},
5294a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY},
5295d7be54ccSKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT},
5296a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE},
5297a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING},
5298a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP},
5299a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO},
5300a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR}
5301a36c61f9SKrishna Gudipati };
5302a36c61f9SKrishna Gudipati 
53035fbe25c7SJing Huang /*
5304a36c61f9SKrishna Gudipati  * Beginning state.
5305a36c61f9SKrishna Gudipati  */
5306a36c61f9SKrishna Gudipati static void
5307a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
5308a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5309a36c61f9SKrishna Gudipati {
5310a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5311a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5312a36c61f9SKrishna Gudipati 
5313a36c61f9SKrishna Gudipati 	switch (event) {
5314a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_CREATE:
5315a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5316a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_addvport(__vport_fabric(vport), vport);
5317a36c61f9SKrishna Gudipati 		break;
5318a36c61f9SKrishna Gudipati 
5319a36c61f9SKrishna Gudipati 	default:
5320a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5321a36c61f9SKrishna Gudipati 	}
5322a36c61f9SKrishna Gudipati }
5323a36c61f9SKrishna Gudipati 
53245fbe25c7SJing Huang /*
5325a36c61f9SKrishna Gudipati  * Created state - a start event is required to start up the state machine.
5326a36c61f9SKrishna Gudipati  */
5327a36c61f9SKrishna Gudipati static void
5328a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
5329a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5330a36c61f9SKrishna Gudipati {
5331a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5332a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5333a36c61f9SKrishna Gudipati 
5334a36c61f9SKrishna Gudipati 	switch (event) {
5335a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_START:
5336f7f73812SMaggie Zhang 		if (bfa_sm_cmp_state(__vport_fabric(vport),
5337f7f73812SMaggie Zhang 					bfa_fcs_fabric_sm_online)
5338a36c61f9SKrishna Gudipati 		    && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) {
5339a36c61f9SKrishna Gudipati 			bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5340a36c61f9SKrishna Gudipati 			bfa_fcs_vport_do_fdisc(vport);
5341a36c61f9SKrishna Gudipati 		} else {
53425fbe25c7SJing Huang 			/*
5343a36c61f9SKrishna Gudipati 			 * Fabric is offline or not NPIV capable, stay in
5344a36c61f9SKrishna Gudipati 			 * offline state.
5345a36c61f9SKrishna Gudipati 			 */
5346a36c61f9SKrishna Gudipati 			vport->vport_stats.fab_no_npiv++;
5347a36c61f9SKrishna Gudipati 			bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5348a36c61f9SKrishna Gudipati 		}
5349a36c61f9SKrishna Gudipati 		break;
5350a36c61f9SKrishna Gudipati 
5351a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5352a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5353a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5354a36c61f9SKrishna Gudipati 		break;
5355a36c61f9SKrishna Gudipati 
5356a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_ONLINE:
5357a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
53585fbe25c7SJing Huang 		/*
5359a36c61f9SKrishna Gudipati 		 * Ignore ONLINE/OFFLINE events from fabric
5360a36c61f9SKrishna Gudipati 		 * till vport is started.
5361a36c61f9SKrishna Gudipati 		 */
5362a36c61f9SKrishna Gudipati 		break;
5363a36c61f9SKrishna Gudipati 
5364a36c61f9SKrishna Gudipati 	default:
5365a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5366a36c61f9SKrishna Gudipati 	}
5367a36c61f9SKrishna Gudipati }
5368a36c61f9SKrishna Gudipati 
53695fbe25c7SJing Huang /*
5370a36c61f9SKrishna Gudipati  * Offline state - awaiting ONLINE event from fabric SM.
5371a36c61f9SKrishna Gudipati  */
5372a36c61f9SKrishna Gudipati static void
5373a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
5374a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5375a36c61f9SKrishna Gudipati {
5376a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5377a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5378a36c61f9SKrishna Gudipati 
5379a36c61f9SKrishna Gudipati 	switch (event) {
5380a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5381a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5382a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5383a36c61f9SKrishna Gudipati 		break;
5384a36c61f9SKrishna Gudipati 
5385a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_ONLINE:
5386a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5387a36c61f9SKrishna Gudipati 		vport->fdisc_retries = 0;
5388a36c61f9SKrishna Gudipati 		bfa_fcs_vport_do_fdisc(vport);
5389a36c61f9SKrishna Gudipati 		break;
5390a36c61f9SKrishna Gudipati 
5391dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOP:
5392dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5393dd5aaf45SKrishna Gudipati 		bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
5394dd5aaf45SKrishna Gudipati 		break;
5395dd5aaf45SKrishna Gudipati 
5396a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5397a36c61f9SKrishna Gudipati 		/*
5398a36c61f9SKrishna Gudipati 		 * This can happen if the vport couldn't be initialzied
5399a36c61f9SKrishna Gudipati 		 * due the fact that the npiv was not enabled on the switch.
5400a36c61f9SKrishna Gudipati 		 * In that case we will put the vport in offline state.
5401a36c61f9SKrishna Gudipati 		 * However, the link can go down and cause the this event to
5402a36c61f9SKrishna Gudipati 		 * be sent when we are already offline. Ignore it.
5403a36c61f9SKrishna Gudipati 		 */
5404a36c61f9SKrishna Gudipati 		break;
5405a36c61f9SKrishna Gudipati 
5406a36c61f9SKrishna Gudipati 	default:
5407a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5408a36c61f9SKrishna Gudipati 	}
5409a36c61f9SKrishna Gudipati }
5410a36c61f9SKrishna Gudipati 
5411a36c61f9SKrishna Gudipati 
54125fbe25c7SJing Huang /*
5413a36c61f9SKrishna Gudipati  * FDISC is sent and awaiting reply from fabric.
5414a36c61f9SKrishna Gudipati  */
5415a36c61f9SKrishna Gudipati static void
5416a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
5417a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5418a36c61f9SKrishna Gudipati {
5419a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5420a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5421a36c61f9SKrishna Gudipati 
5422a36c61f9SKrishna Gudipati 	switch (event) {
5423a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5424d7be54ccSKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait);
5425a36c61f9SKrishna Gudipati 		break;
5426a36c61f9SKrishna Gudipati 
5427a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5428a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5429f7f73812SMaggie Zhang 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5430a36c61f9SKrishna Gudipati 		break;
5431a36c61f9SKrishna Gudipati 
5432a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
5433a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_online);
5434a36c61f9SKrishna Gudipati 		bfa_fcs_lport_online(&vport->lport);
5435a36c61f9SKrishna Gudipati 		break;
5436a36c61f9SKrishna Gudipati 
5437a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
5438a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry);
5439a36c61f9SKrishna Gudipati 		bfa_timer_start(__vport_bfa(vport), &vport->timer,
5440a36c61f9SKrishna Gudipati 				    bfa_fcs_vport_timeout, vport,
5441a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
5442a36c61f9SKrishna Gudipati 		break;
5443a36c61f9SKrishna Gudipati 
5444a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_FAILED:
5445a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5446a36c61f9SKrishna Gudipati 		break;
5447a36c61f9SKrishna Gudipati 
5448a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
5449a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_error);
5450a36c61f9SKrishna Gudipati 		break;
5451a36c61f9SKrishna Gudipati 
5452a36c61f9SKrishna Gudipati 	default:
5453a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5454a36c61f9SKrishna Gudipati 	}
5455a36c61f9SKrishna Gudipati }
5456a36c61f9SKrishna Gudipati 
54575fbe25c7SJing Huang /*
5458a36c61f9SKrishna Gudipati  * FDISC attempt failed - a timer is active to retry FDISC.
5459a36c61f9SKrishna Gudipati  */
5460a36c61f9SKrishna Gudipati static void
5461a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
5462a36c61f9SKrishna Gudipati 			     enum bfa_fcs_vport_event event)
5463a36c61f9SKrishna Gudipati {
5464a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5465a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5466a36c61f9SKrishna Gudipati 
5467a36c61f9SKrishna Gudipati 	switch (event) {
5468a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5469a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5470a36c61f9SKrishna Gudipati 		bfa_timer_stop(&vport->timer);
5471a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5472a36c61f9SKrishna Gudipati 		break;
5473a36c61f9SKrishna Gudipati 
5474a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5475a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5476a36c61f9SKrishna Gudipati 		bfa_timer_stop(&vport->timer);
5477a36c61f9SKrishna Gudipati 		break;
5478a36c61f9SKrishna Gudipati 
5479a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_TIMEOUT:
5480a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5481a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_retries++;
5482a36c61f9SKrishna Gudipati 		vport->fdisc_retries++;
5483a36c61f9SKrishna Gudipati 		bfa_fcs_vport_do_fdisc(vport);
5484a36c61f9SKrishna Gudipati 		break;
5485a36c61f9SKrishna Gudipati 
5486a36c61f9SKrishna Gudipati 	default:
5487a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5488a36c61f9SKrishna Gudipati 	}
5489a36c61f9SKrishna Gudipati }
5490a36c61f9SKrishna Gudipati 
54915fbe25c7SJing Huang /*
5492d7be54ccSKrishna Gudipati  * FDISC is in progress and we got a vport delete request -
5493d7be54ccSKrishna Gudipati  * this is a wait state while we wait for fdisc response and
5494d7be54ccSKrishna Gudipati  * we will transition to the appropriate state - on rsp status.
5495d7be54ccSKrishna Gudipati  */
5496d7be54ccSKrishna Gudipati static void
5497d7be54ccSKrishna Gudipati bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
5498d7be54ccSKrishna Gudipati 				enum bfa_fcs_vport_event event)
5499d7be54ccSKrishna Gudipati {
5500d7be54ccSKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5501d7be54ccSKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5502d7be54ccSKrishna Gudipati 
5503d7be54ccSKrishna Gudipati 	switch (event) {
5504d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
5505d7be54ccSKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
5506d7be54ccSKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5507d7be54ccSKrishna Gudipati 		break;
5508d7be54ccSKrishna Gudipati 
5509d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5510d7be54ccSKrishna Gudipati 		break;
5511d7be54ccSKrishna Gudipati 
5512d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5513d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
5514d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_FAILED:
5515d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
5516d7be54ccSKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5517d7be54ccSKrishna Gudipati 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5518d7be54ccSKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5519d7be54ccSKrishna Gudipati 		break;
5520d7be54ccSKrishna Gudipati 
5521d7be54ccSKrishna Gudipati 	default:
5522d7be54ccSKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5523d7be54ccSKrishna Gudipati 	}
5524d7be54ccSKrishna Gudipati }
5525d7be54ccSKrishna Gudipati 
5526d7be54ccSKrishna Gudipati /*
5527a36c61f9SKrishna Gudipati  * Vport is online (FDISC is complete).
5528a36c61f9SKrishna Gudipati  */
5529a36c61f9SKrishna Gudipati static void
5530a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
5531a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5532a36c61f9SKrishna Gudipati {
5533a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5534a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5535a36c61f9SKrishna Gudipati 
5536a36c61f9SKrishna Gudipati 	switch (event) {
5537a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5538a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
5539a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5540a36c61f9SKrishna Gudipati 		break;
5541a36c61f9SKrishna Gudipati 
5542dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOP:
5543dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping);
5544dd5aaf45SKrishna Gudipati 		bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
5545dd5aaf45SKrishna Gudipati 		break;
5546dd5aaf45SKrishna Gudipati 
5547a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5548a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5549f7f73812SMaggie Zhang 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5550a36c61f9SKrishna Gudipati 		bfa_fcs_lport_offline(&vport->lport);
5551a36c61f9SKrishna Gudipati 		break;
5552a36c61f9SKrishna Gudipati 
5553a36c61f9SKrishna Gudipati 	default:
5554a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5555a36c61f9SKrishna Gudipati 	}
5556a36c61f9SKrishna Gudipati }
5557a36c61f9SKrishna Gudipati 
55585fbe25c7SJing Huang /*
5559dd5aaf45SKrishna Gudipati  * Vport is being stopped - awaiting lport stop completion to send
5560dd5aaf45SKrishna Gudipati  * LOGO to fabric.
5561dd5aaf45SKrishna Gudipati  */
5562dd5aaf45SKrishna Gudipati static void
5563dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
5564dd5aaf45SKrishna Gudipati 			  enum bfa_fcs_vport_event event)
5565dd5aaf45SKrishna Gudipati {
5566dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5567dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5568dd5aaf45SKrishna Gudipati 
5569dd5aaf45SKrishna Gudipati 	switch (event) {
5570dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOPCOMP:
5571dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop);
5572dd5aaf45SKrishna Gudipati 		bfa_fcs_vport_do_logo(vport);
5573dd5aaf45SKrishna Gudipati 		break;
5574dd5aaf45SKrishna Gudipati 
5575dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5576dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5577dd5aaf45SKrishna Gudipati 		break;
5578dd5aaf45SKrishna Gudipati 
5579dd5aaf45SKrishna Gudipati 	default:
5580dd5aaf45SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5581dd5aaf45SKrishna Gudipati 	}
5582dd5aaf45SKrishna Gudipati }
5583dd5aaf45SKrishna Gudipati 
5584dd5aaf45SKrishna Gudipati /*
5585a36c61f9SKrishna Gudipati  * Vport is being deleted - awaiting lport delete completion to send
5586a36c61f9SKrishna Gudipati  * LOGO to fabric.
5587a36c61f9SKrishna Gudipati  */
5588a36c61f9SKrishna Gudipati static void
5589a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
5590a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5591a36c61f9SKrishna Gudipati {
5592a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5593a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5594a36c61f9SKrishna Gudipati 
5595a36c61f9SKrishna Gudipati 	switch (event) {
5596a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5597a36c61f9SKrishna Gudipati 		break;
5598a36c61f9SKrishna Gudipati 
5599a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELCOMP:
5600a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
5601a36c61f9SKrishna Gudipati 		bfa_fcs_vport_do_logo(vport);
5602a36c61f9SKrishna Gudipati 		break;
5603a36c61f9SKrishna Gudipati 
5604a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5605a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5606a36c61f9SKrishna Gudipati 		break;
5607a36c61f9SKrishna Gudipati 
5608a36c61f9SKrishna Gudipati 	default:
5609a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5610a36c61f9SKrishna Gudipati 	}
5611a36c61f9SKrishna Gudipati }
5612a36c61f9SKrishna Gudipati 
56135fbe25c7SJing Huang /*
5614a36c61f9SKrishna Gudipati  * Error State.
5615a36c61f9SKrishna Gudipati  * This state will be set when the Vport Creation fails due
5616a36c61f9SKrishna Gudipati  * to errors like Dup WWN. In this state only operation allowed
5617a36c61f9SKrishna Gudipati  * is a Vport Delete.
5618a36c61f9SKrishna Gudipati  */
5619a36c61f9SKrishna Gudipati static void
5620a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
5621a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5622a36c61f9SKrishna Gudipati {
5623a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5624a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5625a36c61f9SKrishna Gudipati 
5626a36c61f9SKrishna Gudipati 	switch (event) {
5627a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5628a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5629a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
5630a36c61f9SKrishna Gudipati 		break;
5631a36c61f9SKrishna Gudipati 
5632a36c61f9SKrishna Gudipati 	default:
5633a36c61f9SKrishna Gudipati 		bfa_trc(__vport_fcs(vport), event);
5634a36c61f9SKrishna Gudipati 	}
5635a36c61f9SKrishna Gudipati }
5636a36c61f9SKrishna Gudipati 
56375fbe25c7SJing Huang /*
5638a36c61f9SKrishna Gudipati  * Lport cleanup is in progress since vport is being deleted. Fabric is
5639a36c61f9SKrishna Gudipati  * offline, so no LOGO is needed to complete vport deletion.
5640a36c61f9SKrishna Gudipati  */
5641a36c61f9SKrishna Gudipati static void
5642a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
5643a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5644a36c61f9SKrishna Gudipati {
5645a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5646a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5647a36c61f9SKrishna Gudipati 
5648a36c61f9SKrishna Gudipati 	switch (event) {
5649a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELCOMP:
5650a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5651a36c61f9SKrishna Gudipati 		bfa_fcs_vport_free(vport);
5652a36c61f9SKrishna Gudipati 		break;
5653a36c61f9SKrishna Gudipati 
5654dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOPCOMP:
5655dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5656dd5aaf45SKrishna Gudipati 		break;
5657dd5aaf45SKrishna Gudipati 
5658a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5659a36c61f9SKrishna Gudipati 		break;
5660a36c61f9SKrishna Gudipati 
5661a36c61f9SKrishna Gudipati 	default:
5662a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5663a36c61f9SKrishna Gudipati 	}
5664a36c61f9SKrishna Gudipati }
5665a36c61f9SKrishna Gudipati 
56665fbe25c7SJing Huang /*
5667dd5aaf45SKrishna Gudipati  * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup
5668dd5aaf45SKrishna Gudipati  * is done.
5669dd5aaf45SKrishna Gudipati  */
5670dd5aaf45SKrishna Gudipati static void
5671dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
5672dd5aaf45SKrishna Gudipati 			       enum bfa_fcs_vport_event event)
5673dd5aaf45SKrishna Gudipati {
5674dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5675dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5676dd5aaf45SKrishna Gudipati 
5677dd5aaf45SKrishna Gudipati 	switch (event) {
5678dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5679dd5aaf45SKrishna Gudipati 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5680dd5aaf45SKrishna Gudipati 		/*
5681dd5aaf45SKrishna Gudipati 		 * !!! fall through !!!
5682dd5aaf45SKrishna Gudipati 		 */
5683dd5aaf45SKrishna Gudipati 
5684dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
5685dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
5686dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5687dd5aaf45SKrishna Gudipati 		break;
5688dd5aaf45SKrishna Gudipati 
5689dd5aaf45SKrishna Gudipati 	default:
5690dd5aaf45SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5691dd5aaf45SKrishna Gudipati 	}
5692dd5aaf45SKrishna Gudipati }
5693dd5aaf45SKrishna Gudipati 
5694dd5aaf45SKrishna Gudipati /*
5695a36c61f9SKrishna Gudipati  * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
5696a36c61f9SKrishna Gudipati  * is done.
5697a36c61f9SKrishna Gudipati  */
5698a36c61f9SKrishna Gudipati static void
5699a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
5700a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
5701a36c61f9SKrishna Gudipati {
5702a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5703a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
5704a36c61f9SKrishna Gudipati 
5705a36c61f9SKrishna Gudipati 	switch (event) {
5706a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
5707f7f73812SMaggie Zhang 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
5708a36c61f9SKrishna Gudipati 		/*
5709a36c61f9SKrishna Gudipati 		 * !!! fall through !!!
5710a36c61f9SKrishna Gudipati 		 */
5711a36c61f9SKrishna Gudipati 
5712a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
5713a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
5714a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5715a36c61f9SKrishna Gudipati 		bfa_fcs_vport_free(vport);
5716a36c61f9SKrishna Gudipati 		break;
5717a36c61f9SKrishna Gudipati 
5718a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
5719a36c61f9SKrishna Gudipati 		break;
5720a36c61f9SKrishna Gudipati 
5721a36c61f9SKrishna Gudipati 	default:
5722a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
5723a36c61f9SKrishna Gudipati 	}
5724a36c61f9SKrishna Gudipati }
5725a36c61f9SKrishna Gudipati 
5726a36c61f9SKrishna Gudipati 
5727a36c61f9SKrishna Gudipati 
57285fbe25c7SJing Huang /*
5729a36c61f9SKrishna Gudipati  *  fcs_vport_private FCS virtual port private functions
5730a36c61f9SKrishna Gudipati  */
57315fbe25c7SJing Huang /*
57327826f304SKrishna Gudipati  * Send AEN notification
57337826f304SKrishna Gudipati  */
57347826f304SKrishna Gudipati static void
57357826f304SKrishna Gudipati bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port,
57367826f304SKrishna Gudipati 		       enum bfa_lport_aen_event event)
57377826f304SKrishna Gudipati {
57387826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
57397826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
57407826f304SKrishna Gudipati 
57417826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
57427826f304SKrishna Gudipati 	if (!aen_entry)
57437826f304SKrishna Gudipati 		return;
57447826f304SKrishna Gudipati 
57457826f304SKrishna Gudipati 	aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
57467826f304SKrishna Gudipati 	aen_entry->aen_data.lport.roles = port->port_cfg.roles;
57477826f304SKrishna Gudipati 	aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
57487826f304SKrishna Gudipati 					bfa_fcs_get_base_port(port->fcs));
57497826f304SKrishna Gudipati 	aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
57507826f304SKrishna Gudipati 
57517826f304SKrishna Gudipati 	/* Send the AEN notification */
57527826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
57537826f304SKrishna Gudipati 				  BFA_AEN_CAT_LPORT, event);
57547826f304SKrishna Gudipati }
57557826f304SKrishna Gudipati 
57567826f304SKrishna Gudipati /*
5757a36c61f9SKrishna Gudipati  * This routine will be called to send a FDISC command.
5758a36c61f9SKrishna Gudipati  */
5759a36c61f9SKrishna Gudipati static void
5760a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
5761a36c61f9SKrishna Gudipati {
5762a36c61f9SKrishna Gudipati 	bfa_lps_fdisc(vport->lps, vport,
5763a36c61f9SKrishna Gudipati 		bfa_fcport_get_maxfrsize(__vport_bfa(vport)),
5764a36c61f9SKrishna Gudipati 		__vport_pwwn(vport), __vport_nwwn(vport));
5765a36c61f9SKrishna Gudipati 	vport->vport_stats.fdisc_sent++;
5766a36c61f9SKrishna Gudipati }
5767a36c61f9SKrishna Gudipati 
5768a36c61f9SKrishna Gudipati static void
5769a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
5770a36c61f9SKrishna Gudipati {
5771f7f73812SMaggie Zhang 	u8		lsrjt_rsn = vport->lps->lsrjt_rsn;
5772f7f73812SMaggie Zhang 	u8		lsrjt_expl = vport->lps->lsrjt_expl;
5773a36c61f9SKrishna Gudipati 
5774a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), lsrjt_rsn);
5775a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), lsrjt_expl);
5776a36c61f9SKrishna Gudipati 
5777a36c61f9SKrishna Gudipati 	/* For certain reason codes, we don't want to retry. */
5778f7f73812SMaggie Zhang 	switch (vport->lps->lsrjt_expl) {
5779a36c61f9SKrishna Gudipati 	case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */
5780a36c61f9SKrishna Gudipati 	case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
5781a36c61f9SKrishna Gudipati 		if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
5782a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
57837826f304SKrishna Gudipati 		else {
57847826f304SKrishna Gudipati 			bfa_fcs_vport_aen_post(&vport->lport,
57857826f304SKrishna Gudipati 					BFA_LPORT_AEN_NPIV_DUP_WWN);
5786a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN);
57877826f304SKrishna Gudipati 		}
5788a36c61f9SKrishna Gudipati 		break;
5789a36c61f9SKrishna Gudipati 
5790a36c61f9SKrishna Gudipati 	case FC_LS_RJT_EXP_INSUFF_RES:
5791a36c61f9SKrishna Gudipati 		/*
5792a36c61f9SKrishna Gudipati 		 * This means max logins per port/switch setting on the
5793a36c61f9SKrishna Gudipati 		 * switch was exceeded.
5794a36c61f9SKrishna Gudipati 		 */
5795a36c61f9SKrishna Gudipati 		if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
5796a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
57977826f304SKrishna Gudipati 		else {
57987826f304SKrishna Gudipati 			bfa_fcs_vport_aen_post(&vport->lport,
57997826f304SKrishna Gudipati 					BFA_LPORT_AEN_NPIV_FABRIC_MAX);
5800a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
58017826f304SKrishna Gudipati 		}
5802a36c61f9SKrishna Gudipati 		break;
5803a36c61f9SKrishna Gudipati 
5804a36c61f9SKrishna Gudipati 	default:
58057826f304SKrishna Gudipati 		if (vport->fdisc_retries == 0)
58067826f304SKrishna Gudipati 			bfa_fcs_vport_aen_post(&vport->lport,
58077826f304SKrishna Gudipati 					BFA_LPORT_AEN_NPIV_UNKNOWN);
5808a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5809a36c61f9SKrishna Gudipati 	}
5810a36c61f9SKrishna Gudipati }
5811a36c61f9SKrishna Gudipati 
58125fbe25c7SJing Huang /*
5813a36c61f9SKrishna Gudipati  *	Called to send a logout to the fabric. Used when a V-Port is
5814a36c61f9SKrishna Gudipati  *	deleted/stopped.
5815a36c61f9SKrishna Gudipati  */
5816a36c61f9SKrishna Gudipati static void
5817a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport)
5818a36c61f9SKrishna Gudipati {
5819a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5820a36c61f9SKrishna Gudipati 
5821a36c61f9SKrishna Gudipati 	vport->vport_stats.logo_sent++;
5822a36c61f9SKrishna Gudipati 	bfa_lps_fdisclogo(vport->lps);
5823a36c61f9SKrishna Gudipati }
5824a36c61f9SKrishna Gudipati 
5825a36c61f9SKrishna Gudipati 
58265fbe25c7SJing Huang /*
5827a36c61f9SKrishna Gudipati  *     This routine will be called by bfa_timer on timer timeouts.
5828a36c61f9SKrishna Gudipati  *
5829a36c61f9SKrishna Gudipati  *	param[in]	vport		- pointer to bfa_fcs_vport_t.
5830a36c61f9SKrishna Gudipati  *	param[out]	vport_status	- pointer to return vport status in
5831a36c61f9SKrishna Gudipati  *
5832a36c61f9SKrishna Gudipati  *	return
5833a36c61f9SKrishna Gudipati  *		void
5834a36c61f9SKrishna Gudipati  *
5835a36c61f9SKrishna Gudipati  *	Special Considerations:
5836a36c61f9SKrishna Gudipati  *
5837a36c61f9SKrishna Gudipati  *	note
5838a36c61f9SKrishna Gudipati  */
5839a36c61f9SKrishna Gudipati static void
5840a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout(void *vport_arg)
5841a36c61f9SKrishna Gudipati {
5842a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg;
5843a36c61f9SKrishna Gudipati 
5844a36c61f9SKrishna Gudipati 	vport->vport_stats.fdisc_timeouts++;
5845a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT);
5846a36c61f9SKrishna Gudipati }
5847a36c61f9SKrishna Gudipati 
5848a36c61f9SKrishna Gudipati static void
5849a36c61f9SKrishna Gudipati bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
5850a36c61f9SKrishna Gudipati {
5851a36c61f9SKrishna Gudipati 	struct bfad_vport_s *vport_drv =
5852a36c61f9SKrishna Gudipati 			(struct bfad_vport_s *)vport->vport_drv;
5853a36c61f9SKrishna Gudipati 
5854a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
5855a36c61f9SKrishna Gudipati 	bfa_lps_delete(vport->lps);
585617c201b3SKrishna Gudipati 
585717c201b3SKrishna Gudipati 	if (vport_drv->comp_del) {
585817c201b3SKrishna Gudipati 		complete(vport_drv->comp_del);
585917c201b3SKrishna Gudipati 		return;
5860a36c61f9SKrishna Gudipati 	}
5861a36c61f9SKrishna Gudipati 
586217c201b3SKrishna Gudipati 	/*
586317c201b3SKrishna Gudipati 	 * We queue the vport delete work to the IM work_q from here.
586417c201b3SKrishna Gudipati 	 * The memory for the bfad_vport_s is freed from the FC function
586517c201b3SKrishna Gudipati 	 * template vport_delete entry point.
586617c201b3SKrishna Gudipati 	 */
5867529f9a76SKrishna Gudipati 	bfad_im_port_delete(vport_drv->drv_port.bfad, &vport_drv->drv_port);
586817c201b3SKrishna Gudipati }
5869a36c61f9SKrishna Gudipati 
58705fbe25c7SJing Huang /*
5871a36c61f9SKrishna Gudipati  *  fcs_vport_public FCS virtual port public interfaces
5872a36c61f9SKrishna Gudipati  */
5873a36c61f9SKrishna Gudipati 
58745fbe25c7SJing Huang /*
5875a36c61f9SKrishna Gudipati  * Online notification from fabric SM.
5876a36c61f9SKrishna Gudipati  */
5877a36c61f9SKrishna Gudipati void
5878a36c61f9SKrishna Gudipati bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport)
5879a36c61f9SKrishna Gudipati {
5880a36c61f9SKrishna Gudipati 	vport->vport_stats.fab_online++;
5881d7be54ccSKrishna Gudipati 	if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport)))
5882a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
5883d7be54ccSKrishna Gudipati 	else
5884d7be54ccSKrishna Gudipati 		vport->vport_stats.fab_no_npiv++;
5885a36c61f9SKrishna Gudipati }
5886a36c61f9SKrishna Gudipati 
58875fbe25c7SJing Huang /*
5888a36c61f9SKrishna Gudipati  * Offline notification from fabric SM.
5889a36c61f9SKrishna Gudipati  */
5890a36c61f9SKrishna Gudipati void
5891a36c61f9SKrishna Gudipati bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport)
5892a36c61f9SKrishna Gudipati {
5893a36c61f9SKrishna Gudipati 	vport->vport_stats.fab_offline++;
5894a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
5895a36c61f9SKrishna Gudipati }
5896a36c61f9SKrishna Gudipati 
58975fbe25c7SJing Huang /*
5898a36c61f9SKrishna Gudipati  * Cleanup notification from fabric SM on link timer expiry.
5899a36c61f9SKrishna Gudipati  */
5900a36c61f9SKrishna Gudipati void
5901a36c61f9SKrishna Gudipati bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
5902a36c61f9SKrishna Gudipati {
5903a36c61f9SKrishna Gudipati 	vport->vport_stats.fab_cleanup++;
5904a36c61f9SKrishna Gudipati }
5905881c1b3cSKrishna Gudipati 
5906881c1b3cSKrishna Gudipati /*
5907881c1b3cSKrishna Gudipati  * Stop notification from fabric SM. To be invoked from within FCS.
5908881c1b3cSKrishna Gudipati  */
5909881c1b3cSKrishna Gudipati void
5910881c1b3cSKrishna Gudipati bfa_fcs_vport_fcs_stop(struct bfa_fcs_vport_s *vport)
5911881c1b3cSKrishna Gudipati {
5912881c1b3cSKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
5913881c1b3cSKrishna Gudipati }
5914881c1b3cSKrishna Gudipati 
59155fbe25c7SJing Huang /*
5916a36c61f9SKrishna Gudipati  * delete notification from fabric SM. To be invoked from within FCS.
5917a36c61f9SKrishna Gudipati  */
5918a36c61f9SKrishna Gudipati void
5919a36c61f9SKrishna Gudipati bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport)
5920a36c61f9SKrishna Gudipati {
5921a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
5922a36c61f9SKrishna Gudipati }
5923a36c61f9SKrishna Gudipati 
59245fbe25c7SJing Huang /*
5925dd5aaf45SKrishna Gudipati  * Stop completion callback from associated lport
5926dd5aaf45SKrishna Gudipati  */
5927dd5aaf45SKrishna Gudipati void
5928dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport)
5929dd5aaf45SKrishna Gudipati {
5930dd5aaf45SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP);
5931dd5aaf45SKrishna Gudipati }
5932dd5aaf45SKrishna Gudipati 
5933dd5aaf45SKrishna Gudipati /*
5934a36c61f9SKrishna Gudipati  * Delete completion callback from associated lport
5935a36c61f9SKrishna Gudipati  */
5936a36c61f9SKrishna Gudipati void
5937a36c61f9SKrishna Gudipati bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
5938a36c61f9SKrishna Gudipati {
5939a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP);
5940a36c61f9SKrishna Gudipati }
5941a36c61f9SKrishna Gudipati 
5942a36c61f9SKrishna Gudipati 
5943a36c61f9SKrishna Gudipati 
59445fbe25c7SJing Huang /*
5945a36c61f9SKrishna Gudipati  *  fcs_vport_api Virtual port API
5946a36c61f9SKrishna Gudipati  */
5947a36c61f9SKrishna Gudipati 
59485fbe25c7SJing Huang /*
5949a36c61f9SKrishna Gudipati  *	Use this function to instantiate a new FCS vport object. This
5950a36c61f9SKrishna Gudipati  *	function will not trigger any HW initialization process (which will be
5951a36c61f9SKrishna Gudipati  *	done in vport_start() call)
5952a36c61f9SKrishna Gudipati  *
5953a36c61f9SKrishna Gudipati  *	param[in] vport	-		pointer to bfa_fcs_vport_t. This space
5954a36c61f9SKrishna Gudipati  *					needs to be allocated by the driver.
5955a36c61f9SKrishna Gudipati  *	param[in] fcs		-	FCS instance
5956a36c61f9SKrishna Gudipati  *	param[in] vport_cfg	-	vport configuration
5957a36c61f9SKrishna Gudipati  *	param[in] vf_id		-	VF_ID if vport is created within a VF.
5958a36c61f9SKrishna Gudipati  *					FC_VF_ID_NULL to specify base fabric.
5959a36c61f9SKrishna Gudipati  *	param[in] vport_drv	-	Opaque handle back to the driver's vport
5960a36c61f9SKrishna Gudipati  *					structure
5961a36c61f9SKrishna Gudipati  *
5962a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_OK - on success.
5963a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_FAILED - on failure.
5964a36c61f9SKrishna Gudipati  */
5965a36c61f9SKrishna Gudipati bfa_status_t
5966a36c61f9SKrishna Gudipati bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
5967a36c61f9SKrishna Gudipati 		u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
5968a36c61f9SKrishna Gudipati 		struct bfad_vport_s *vport_drv)
5969a36c61f9SKrishna Gudipati {
5970a36c61f9SKrishna Gudipati 	if (vport_cfg->pwwn == 0)
5971a36c61f9SKrishna Gudipati 		return BFA_STATUS_INVALID_WWN;
5972a36c61f9SKrishna Gudipati 
5973a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
5974a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_WWN_BP;
5975a36c61f9SKrishna Gudipati 
5976a36c61f9SKrishna Gudipati 	if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
5977a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_EXISTS;
5978a36c61f9SKrishna Gudipati 
5979f7f73812SMaggie Zhang 	if (fcs->fabric.num_vports ==
5980a36c61f9SKrishna Gudipati 			bfa_lps_get_max_vport(fcs->bfa))
5981a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_MAX;
5982a36c61f9SKrishna Gudipati 
5983a36c61f9SKrishna Gudipati 	vport->lps = bfa_lps_alloc(fcs->bfa);
5984a36c61f9SKrishna Gudipati 	if (!vport->lps)
5985a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_MAX;
5986a36c61f9SKrishna Gudipati 
5987a36c61f9SKrishna Gudipati 	vport->vport_drv = vport_drv;
5988a36c61f9SKrishna Gudipati 	vport_cfg->preboot_vp = BFA_FALSE;
5989a36c61f9SKrishna Gudipati 
5990a36c61f9SKrishna Gudipati 	bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
5991a36c61f9SKrishna Gudipati 	bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
5992a36c61f9SKrishna Gudipati 	bfa_fcs_lport_init(&vport->lport, vport_cfg);
5993a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
5994a36c61f9SKrishna Gudipati 
5995a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
5996a36c61f9SKrishna Gudipati }
5997a36c61f9SKrishna Gudipati 
59985fbe25c7SJing Huang /*
5999a36c61f9SKrishna Gudipati  *	Use this function to instantiate a new FCS PBC vport object. This
6000a36c61f9SKrishna Gudipati  *	function will not trigger any HW initialization process (which will be
6001a36c61f9SKrishna Gudipati  *	done in vport_start() call)
6002a36c61f9SKrishna Gudipati  *
6003a36c61f9SKrishna Gudipati  *	param[in] vport	-	pointer to bfa_fcs_vport_t. This space
6004a36c61f9SKrishna Gudipati  *				needs to be allocated by the driver.
6005a36c61f9SKrishna Gudipati  *	param[in] fcs	-	FCS instance
6006a36c61f9SKrishna Gudipati  *	param[in] vport_cfg	-	vport configuration
6007a36c61f9SKrishna Gudipati  *	param[in] vf_id		-	VF_ID if vport is created within a VF.
6008a36c61f9SKrishna Gudipati  *					FC_VF_ID_NULL to specify base fabric.
6009a36c61f9SKrishna Gudipati  *	param[in] vport_drv	-	Opaque handle back to the driver's vport
6010a36c61f9SKrishna Gudipati  *					structure
6011a36c61f9SKrishna Gudipati  *
6012a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_OK - on success.
6013a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_FAILED - on failure.
6014a36c61f9SKrishna Gudipati  */
6015a36c61f9SKrishna Gudipati bfa_status_t
6016a36c61f9SKrishna Gudipati bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
6017a36c61f9SKrishna Gudipati 			u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
6018a36c61f9SKrishna Gudipati 			struct bfad_vport_s *vport_drv)
6019a36c61f9SKrishna Gudipati {
6020a36c61f9SKrishna Gudipati 	bfa_status_t rc;
6021a36c61f9SKrishna Gudipati 
6022a36c61f9SKrishna Gudipati 	rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv);
6023a36c61f9SKrishna Gudipati 	vport->lport.port_cfg.preboot_vp = BFA_TRUE;
6024a36c61f9SKrishna Gudipati 
6025a36c61f9SKrishna Gudipati 	return rc;
6026a36c61f9SKrishna Gudipati }
6027a36c61f9SKrishna Gudipati 
60285fbe25c7SJing Huang /*
6029a36c61f9SKrishna Gudipati  *	Use this function to findout if this is a pbc vport or not.
6030a36c61f9SKrishna Gudipati  *
6031a36c61f9SKrishna Gudipati  * @param[in] vport - pointer to bfa_fcs_vport_t.
6032a36c61f9SKrishna Gudipati  *
6033a36c61f9SKrishna Gudipati  * @returns None
6034a36c61f9SKrishna Gudipati  */
6035a36c61f9SKrishna Gudipati bfa_boolean_t
6036a36c61f9SKrishna Gudipati bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport)
6037a36c61f9SKrishna Gudipati {
6038a36c61f9SKrishna Gudipati 
6039a36c61f9SKrishna Gudipati 	if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE))
6040a36c61f9SKrishna Gudipati 		return BFA_TRUE;
6041a36c61f9SKrishna Gudipati 	else
6042a36c61f9SKrishna Gudipati 		return BFA_FALSE;
6043a36c61f9SKrishna Gudipati 
6044a36c61f9SKrishna Gudipati }
6045a36c61f9SKrishna Gudipati 
60465fbe25c7SJing Huang /*
6047a36c61f9SKrishna Gudipati  * Use this function initialize the vport.
6048a36c61f9SKrishna Gudipati  *
6049a36c61f9SKrishna Gudipati  * @param[in] vport - pointer to bfa_fcs_vport_t.
6050a36c61f9SKrishna Gudipati  *
6051a36c61f9SKrishna Gudipati  * @returns None
6052a36c61f9SKrishna Gudipati  */
6053a36c61f9SKrishna Gudipati bfa_status_t
6054a36c61f9SKrishna Gudipati bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport)
6055a36c61f9SKrishna Gudipati {
6056a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START);
6057a36c61f9SKrishna Gudipati 
6058a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
6059a36c61f9SKrishna Gudipati }
6060a36c61f9SKrishna Gudipati 
60615fbe25c7SJing Huang /*
6062a36c61f9SKrishna Gudipati  *	Use this function quiese the vport object. This function will return
6063a36c61f9SKrishna Gudipati  *	immediately, when the vport is actually stopped, the
6064a36c61f9SKrishna Gudipati  *	bfa_drv_vport_stop_cb() will be called.
6065a36c61f9SKrishna Gudipati  *
6066a36c61f9SKrishna Gudipati  *	param[in] vport - pointer to bfa_fcs_vport_t.
6067a36c61f9SKrishna Gudipati  *
6068a36c61f9SKrishna Gudipati  *	return None
6069a36c61f9SKrishna Gudipati  */
6070a36c61f9SKrishna Gudipati bfa_status_t
6071a36c61f9SKrishna Gudipati bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
6072a36c61f9SKrishna Gudipati {
6073a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
6074a36c61f9SKrishna Gudipati 
6075a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
6076a36c61f9SKrishna Gudipati }
6077a36c61f9SKrishna Gudipati 
60785fbe25c7SJing Huang /*
6079a36c61f9SKrishna Gudipati  *	Use this function to delete a vport object. Fabric object should
6080a36c61f9SKrishna Gudipati  *	be stopped before this function call.
6081a36c61f9SKrishna Gudipati  *
6082a36c61f9SKrishna Gudipati  *	!!!!!!! Donot invoke this from within FCS  !!!!!!!
6083a36c61f9SKrishna Gudipati  *
6084a36c61f9SKrishna Gudipati  *	param[in] vport - pointer to bfa_fcs_vport_t.
6085a36c61f9SKrishna Gudipati  *
6086a36c61f9SKrishna Gudipati  *	return     None
6087a36c61f9SKrishna Gudipati  */
6088a36c61f9SKrishna Gudipati bfa_status_t
6089a36c61f9SKrishna Gudipati bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport)
6090a36c61f9SKrishna Gudipati {
6091a36c61f9SKrishna Gudipati 
6092a36c61f9SKrishna Gudipati 	if (vport->lport.port_cfg.preboot_vp)
6093a36c61f9SKrishna Gudipati 		return BFA_STATUS_PBC;
6094a36c61f9SKrishna Gudipati 
6095a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
6096a36c61f9SKrishna Gudipati 
6097a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
6098a36c61f9SKrishna Gudipati }
6099a36c61f9SKrishna Gudipati 
61005fbe25c7SJing Huang /*
6101a36c61f9SKrishna Gudipati  *	Use this function to get vport's current status info.
6102a36c61f9SKrishna Gudipati  *
6103a36c61f9SKrishna Gudipati  *	param[in] vport		pointer to bfa_fcs_vport_t.
6104a36c61f9SKrishna Gudipati  *	param[out] attr		pointer to return vport attributes
6105a36c61f9SKrishna Gudipati  *
6106a36c61f9SKrishna Gudipati  *	return None
6107a36c61f9SKrishna Gudipati  */
6108a36c61f9SKrishna Gudipati void
6109a36c61f9SKrishna Gudipati bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
6110a36c61f9SKrishna Gudipati 			struct bfa_vport_attr_s *attr)
6111a36c61f9SKrishna Gudipati {
6112a36c61f9SKrishna Gudipati 	if (vport == NULL || attr == NULL)
6113a36c61f9SKrishna Gudipati 		return;
6114a36c61f9SKrishna Gudipati 
61156a18b167SJing Huang 	memset(attr, 0, sizeof(struct bfa_vport_attr_s));
6116a36c61f9SKrishna Gudipati 
6117a36c61f9SKrishna Gudipati 	bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr);
6118a36c61f9SKrishna Gudipati 	attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
6119a36c61f9SKrishna Gudipati }
6120a36c61f9SKrishna Gudipati 
6121a36c61f9SKrishna Gudipati 
61225fbe25c7SJing Huang /*
6123a36c61f9SKrishna Gudipati  *	Lookup a virtual port. Excludes base port from lookup.
6124a36c61f9SKrishna Gudipati  */
6125a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *
6126a36c61f9SKrishna Gudipati bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn)
6127a36c61f9SKrishna Gudipati {
6128a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
6129a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
6130a36c61f9SKrishna Gudipati 
6131a36c61f9SKrishna Gudipati 	bfa_trc(fcs, vf_id);
6132a36c61f9SKrishna Gudipati 	bfa_trc(fcs, vpwwn);
6133a36c61f9SKrishna Gudipati 
6134a36c61f9SKrishna Gudipati 	fabric = bfa_fcs_vf_lookup(fcs, vf_id);
6135a36c61f9SKrishna Gudipati 	if (!fabric) {
6136a36c61f9SKrishna Gudipati 		bfa_trc(fcs, vf_id);
6137a36c61f9SKrishna Gudipati 		return NULL;
6138a36c61f9SKrishna Gudipati 	}
6139a36c61f9SKrishna Gudipati 
6140a36c61f9SKrishna Gudipati 	vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn);
6141a36c61f9SKrishna Gudipati 	return vport;
6142a36c61f9SKrishna Gudipati }
6143a36c61f9SKrishna Gudipati 
61445fbe25c7SJing Huang /*
6145a36c61f9SKrishna Gudipati  * FDISC Response
6146a36c61f9SKrishna Gudipati  */
6147a36c61f9SKrishna Gudipati void
6148a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
6149a36c61f9SKrishna Gudipati {
6150a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = uarg;
6151a36c61f9SKrishna Gudipati 
6152a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6153a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), status);
6154a36c61f9SKrishna Gudipati 
6155a36c61f9SKrishna Gudipati 	switch (status) {
6156a36c61f9SKrishna Gudipati 	case BFA_STATUS_OK:
6157a36c61f9SKrishna Gudipati 		/*
6158b595076aSUwe Kleine-König 		 * Initialize the V-Port fields
6159a36c61f9SKrishna Gudipati 		 */
6160f7f73812SMaggie Zhang 		__vport_fcid(vport) = vport->lps->lp_pid;
6161a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_accepts++;
6162a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
6163a36c61f9SKrishna Gudipati 		break;
6164a36c61f9SKrishna Gudipati 
6165a36c61f9SKrishna Gudipati 	case BFA_STATUS_INVALID_MAC:
6166a36c61f9SKrishna Gudipati 		/* Only for CNA */
6167a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_acc_bad++;
6168a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6169a36c61f9SKrishna Gudipati 
6170a36c61f9SKrishna Gudipati 		break;
6171a36c61f9SKrishna Gudipati 
6172a36c61f9SKrishna Gudipati 	case BFA_STATUS_EPROTOCOL:
6173f7f73812SMaggie Zhang 		switch (vport->lps->ext_status) {
6174a36c61f9SKrishna Gudipati 		case BFA_EPROTO_BAD_ACCEPT:
6175a36c61f9SKrishna Gudipati 			vport->vport_stats.fdisc_acc_bad++;
6176a36c61f9SKrishna Gudipati 			break;
6177a36c61f9SKrishna Gudipati 
6178a36c61f9SKrishna Gudipati 		case BFA_EPROTO_UNKNOWN_RSP:
6179a36c61f9SKrishna Gudipati 			vport->vport_stats.fdisc_unknown_rsp++;
6180a36c61f9SKrishna Gudipati 			break;
6181a36c61f9SKrishna Gudipati 
6182a36c61f9SKrishna Gudipati 		default:
6183a36c61f9SKrishna Gudipati 			break;
6184a36c61f9SKrishna Gudipati 		}
6185a36c61f9SKrishna Gudipati 
6186a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6187a36c61f9SKrishna Gudipati 		break;
6188a36c61f9SKrishna Gudipati 
6189a36c61f9SKrishna Gudipati 	case BFA_STATUS_FABRIC_RJT:
6190a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_rejects++;
6191a36c61f9SKrishna Gudipati 		bfa_fcs_vport_fdisc_rejected(vport);
6192a36c61f9SKrishna Gudipati 		break;
6193a36c61f9SKrishna Gudipati 
6194a36c61f9SKrishna Gudipati 	default:
6195a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_rsp_err++;
6196a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6197a36c61f9SKrishna Gudipati 	}
6198a36c61f9SKrishna Gudipati }
6199a36c61f9SKrishna Gudipati 
62005fbe25c7SJing Huang /*
6201a36c61f9SKrishna Gudipati  * LOGO response
6202a36c61f9SKrishna Gudipati  */
6203a36c61f9SKrishna Gudipati void
6204a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
6205a36c61f9SKrishna Gudipati {
6206a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = uarg;
6207a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
6208a36c61f9SKrishna Gudipati }
6209a36c61f9SKrishna Gudipati 
62105fbe25c7SJing Huang /*
6211a36c61f9SKrishna Gudipati  * Received clear virtual link
6212a36c61f9SKrishna Gudipati  */
6213a36c61f9SKrishna Gudipati void
6214a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(void *bfad, void *uarg)
6215a36c61f9SKrishna Gudipati {
6216a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = uarg;
6217a36c61f9SKrishna Gudipati 
6218a36c61f9SKrishna Gudipati 	/* Send an Offline followed by an ONLINE */
6219a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
6220a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
6221a36c61f9SKrishna Gudipati }
6222