xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs_lport.c (revision 22a08538)
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 
26bc0e2c2aSKrishna Gudipati /*
27bc0e2c2aSKrishna Gudipati  * ALPA to LIXA bitmap mapping
28bc0e2c2aSKrishna Gudipati  *
29bc0e2c2aSKrishna Gudipati  * ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31
30bc0e2c2aSKrishna Gudipati  * is for L_bit (login required) and is filled as ALPA 0x00 here.
31bc0e2c2aSKrishna Gudipati  */
32bc0e2c2aSKrishna Gudipati static const u8 loop_alpa_map[] = {
33bc0e2c2aSKrishna Gudipati 	0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, /* Word 0 Bits 31..24 */
34bc0e2c2aSKrishna Gudipati 	0x17, 0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25, /* Word 0 Bits 23..16 */
35bc0e2c2aSKrishna Gudipati 	0x26, 0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, /* Word 0 Bits 15..08 */
36bc0e2c2aSKrishna Gudipati 	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, /* Word 0 Bits 07..00 */
37bc0e2c2aSKrishna Gudipati 
38bc0e2c2aSKrishna Gudipati 	0x3C, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, /* Word 1 Bits 31..24 */
39bc0e2c2aSKrishna Gudipati 	0x4C, 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, /* Word 1 Bits 23..16 */
40bc0e2c2aSKrishna Gudipati 	0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67, /* Word 1 Bits 15..08 */
41bc0e2c2aSKrishna Gudipati 	0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, /* Word 1 Bits 07..00 */
42bc0e2c2aSKrishna Gudipati 
43bc0e2c2aSKrishna Gudipati 	0x73, 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, /* Word 2 Bits 31..24 */
44bc0e2c2aSKrishna Gudipati 	0x81, 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, /* Word 2 Bits 23..16 */
45bc0e2c2aSKrishna Gudipati 	0x9B, 0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, /* Word 2 Bits 15..08 */
46bc0e2c2aSKrishna Gudipati 	0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, /* Word 2 Bits 07..00 */
47bc0e2c2aSKrishna Gudipati 
48bc0e2c2aSKrishna Gudipati 	0xB3, 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3, /* Word 3 Bits 31..24 */
49bc0e2c2aSKrishna Gudipati 	0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, /* Word 3 Bits 23..16 */
50bc0e2c2aSKrishna Gudipati 	0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, /* Word 3 Bits 15..08 */
51bc0e2c2aSKrishna Gudipati 	0xDA, 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF, /* Word 3 Bits 07..00 */
52bc0e2c2aSKrishna Gudipati };
53bc0e2c2aSKrishna Gudipati 
54a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port,
557725ccfdSJing Huang 					 struct fchs_s *rx_fchs, u8 reason_code,
567725ccfdSJing Huang 					 u8 reason_code_expl);
57a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
58a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, struct fc_logi_s *plogi);
59a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port);
60a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port);
61a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port);
62a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port);
63a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port);
64a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port);
65a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port,
667725ccfdSJing Huang 			struct fchs_s *rx_fchs,
677725ccfdSJing Huang 			struct fc_echo_s *echo, u16 len);
68a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port,
697725ccfdSJing Huang 			struct fchs_s *rx_fchs,
707725ccfdSJing Huang 			struct fc_rnid_cmd_s *rnid, u16 len);
71a36c61f9SKrishna Gudipati static void     bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
727725ccfdSJing Huang 			struct fc_rnid_general_topology_data_s *gen_topo_data);
737725ccfdSJing Huang 
74a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port);
75a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port);
76a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port);
77a36c61f9SKrishna Gudipati 
78a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port);
79a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port);
80a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port);
81a36c61f9SKrishna Gudipati 
82bc0e2c2aSKrishna Gudipati static void	bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port);
83bc0e2c2aSKrishna Gudipati static void	bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port);
84bc0e2c2aSKrishna Gudipati static void	bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port);
85bc0e2c2aSKrishna Gudipati 
867725ccfdSJing Huang static struct {
87a36c61f9SKrishna Gudipati 	void		(*init) (struct bfa_fcs_lport_s *port);
88a36c61f9SKrishna Gudipati 	void		(*online) (struct bfa_fcs_lport_s *port);
89a36c61f9SKrishna Gudipati 	void		(*offline) (struct bfa_fcs_lport_s *port);
907725ccfdSJing Huang } __port_action[] = {
917725ccfdSJing Huang 	{
92a36c61f9SKrishna Gudipati 	bfa_fcs_lport_unknown_init, bfa_fcs_lport_unknown_online,
93a36c61f9SKrishna Gudipati 			bfa_fcs_lport_unknown_offline}, {
94a36c61f9SKrishna Gudipati 	bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online,
95a36c61f9SKrishna Gudipati 			bfa_fcs_lport_fab_offline}, {
96a36c61f9SKrishna Gudipati 	bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online,
97bc0e2c2aSKrishna Gudipati 			bfa_fcs_lport_n2n_offline}, {
98bc0e2c2aSKrishna Gudipati 	bfa_fcs_lport_loop_init, bfa_fcs_lport_loop_online,
99bc0e2c2aSKrishna Gudipati 			bfa_fcs_lport_loop_offline},
100a36c61f9SKrishna Gudipati 	};
1017725ccfdSJing Huang 
1025fbe25c7SJing Huang /*
1037725ccfdSJing Huang  *  fcs_port_sm FCS logical port state machine
1047725ccfdSJing Huang  */
1057725ccfdSJing Huang 
106a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event {
1077725ccfdSJing Huang 	BFA_FCS_PORT_SM_CREATE = 1,
1087725ccfdSJing Huang 	BFA_FCS_PORT_SM_ONLINE = 2,
1097725ccfdSJing Huang 	BFA_FCS_PORT_SM_OFFLINE = 3,
1107725ccfdSJing Huang 	BFA_FCS_PORT_SM_DELETE = 4,
1117725ccfdSJing Huang 	BFA_FCS_PORT_SM_DELRPORT = 5,
112dd5aaf45SKrishna Gudipati 	BFA_FCS_PORT_SM_STOP = 6,
1137725ccfdSJing Huang };
1147725ccfdSJing Huang 
115a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port,
116a36c61f9SKrishna Gudipati 					enum bfa_fcs_lport_event event);
117a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port,
118a36c61f9SKrishna Gudipati 					enum bfa_fcs_lport_event event);
119a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s *port,
120a36c61f9SKrishna Gudipati 					enum bfa_fcs_lport_event event);
121a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port,
122a36c61f9SKrishna Gudipati 					enum bfa_fcs_lport_event event);
123a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port,
124a36c61f9SKrishna Gudipati 					enum bfa_fcs_lport_event event);
125dd5aaf45SKrishna Gudipati static void	bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
126dd5aaf45SKrishna Gudipati 					enum bfa_fcs_lport_event event);
1277725ccfdSJing Huang 
1287725ccfdSJing Huang static void
129a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_uninit(
130a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
131a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
1327725ccfdSJing Huang {
1337725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1347725ccfdSJing Huang 	bfa_trc(port->fcs, event);
1357725ccfdSJing Huang 
1367725ccfdSJing Huang 	switch (event) {
1377725ccfdSJing Huang 	case BFA_FCS_PORT_SM_CREATE:
138a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
1397725ccfdSJing Huang 		break;
1407725ccfdSJing 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_init(struct bfa_fcs_lport_s *port,
148a36c61f9SKrishna Gudipati 			enum bfa_fcs_lport_event event)
1497725ccfdSJing Huang {
1507725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1517725ccfdSJing Huang 	bfa_trc(port->fcs, event);
1527725ccfdSJing Huang 
1537725ccfdSJing Huang 	switch (event) {
1547725ccfdSJing Huang 	case BFA_FCS_PORT_SM_ONLINE:
155a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
156a36c61f9SKrishna Gudipati 		bfa_fcs_lport_online_actions(port);
1577725ccfdSJing Huang 		break;
1587725ccfdSJing Huang 
1597725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELETE:
160a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
161a36c61f9SKrishna Gudipati 		bfa_fcs_lport_deleted(port);
1627725ccfdSJing Huang 		break;
1637725ccfdSJing Huang 
164dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_STOP:
165dd5aaf45SKrishna Gudipati 		/* If vport - send completion call back */
166dd5aaf45SKrishna Gudipati 		if (port->vport)
167dd5aaf45SKrishna Gudipati 			bfa_fcs_vport_stop_comp(port->vport);
168881c1b3cSKrishna Gudipati 		else
169881c1b3cSKrishna Gudipati 			bfa_wc_down(&(port->fabric->stop_wc));
170dd5aaf45SKrishna Gudipati 		break;
171dd5aaf45SKrishna Gudipati 
1723e98cc01SJing Huang 	case BFA_FCS_PORT_SM_OFFLINE:
1733e98cc01SJing Huang 		break;
1743e98cc01SJing Huang 
1757725ccfdSJing Huang 	default:
176e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1777725ccfdSJing Huang 	}
1787725ccfdSJing Huang }
1797725ccfdSJing Huang 
1807725ccfdSJing Huang static void
181a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_online(
182a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
183a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
1847725ccfdSJing Huang {
1857725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
1867725ccfdSJing Huang 	struct list_head		*qe, *qen;
1877725ccfdSJing Huang 
1887725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1897725ccfdSJing Huang 	bfa_trc(port->fcs, event);
1907725ccfdSJing Huang 
1917725ccfdSJing Huang 	switch (event) {
1927725ccfdSJing Huang 	case BFA_FCS_PORT_SM_OFFLINE:
193a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_offline);
194a36c61f9SKrishna Gudipati 		bfa_fcs_lport_offline_actions(port);
1957725ccfdSJing Huang 		break;
1967725ccfdSJing Huang 
197dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_STOP:
198dd5aaf45SKrishna Gudipati 		__port_action[port->fabric->fab_type].offline(port);
199dd5aaf45SKrishna Gudipati 
200dd5aaf45SKrishna Gudipati 		if (port->num_rports == 0) {
201dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
202dd5aaf45SKrishna Gudipati 			/* If vport - send completion call back */
203dd5aaf45SKrishna Gudipati 			if (port->vport)
204dd5aaf45SKrishna Gudipati 				bfa_fcs_vport_stop_comp(port->vport);
205881c1b3cSKrishna Gudipati 			else
206881c1b3cSKrishna Gudipati 				bfa_wc_down(&(port->fabric->stop_wc));
207dd5aaf45SKrishna Gudipati 		} else {
208dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
209dd5aaf45SKrishna Gudipati 			list_for_each_safe(qe, qen, &port->rport_q) {
210dd5aaf45SKrishna Gudipati 				rport = (struct bfa_fcs_rport_s *) qe;
211dd5aaf45SKrishna Gudipati 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
212dd5aaf45SKrishna Gudipati 			}
213dd5aaf45SKrishna Gudipati 		}
214dd5aaf45SKrishna Gudipati 		break;
215dd5aaf45SKrishna Gudipati 
2167725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELETE:
2177725ccfdSJing Huang 
2187725ccfdSJing Huang 		__port_action[port->fabric->fab_type].offline(port);
2197725ccfdSJing Huang 
2207725ccfdSJing Huang 		if (port->num_rports == 0) {
221a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
222a36c61f9SKrishna Gudipati 			bfa_fcs_lport_deleted(port);
2237725ccfdSJing Huang 		} else {
224a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
2257725ccfdSJing Huang 			list_for_each_safe(qe, qen, &port->rport_q) {
2267725ccfdSJing Huang 				rport = (struct bfa_fcs_rport_s *) qe;
227f7f73812SMaggie Zhang 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
2287725ccfdSJing Huang 			}
2297725ccfdSJing Huang 		}
2307725ccfdSJing Huang 		break;
2317725ccfdSJing Huang 
2327725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELRPORT:
2337725ccfdSJing Huang 		break;
2347725ccfdSJing Huang 
2357725ccfdSJing Huang 	default:
236e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
2377725ccfdSJing Huang 	}
2387725ccfdSJing Huang }
2397725ccfdSJing Huang 
2407725ccfdSJing Huang static void
241a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_offline(
242a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
243a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
2447725ccfdSJing Huang {
2457725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
2467725ccfdSJing Huang 	struct list_head		*qe, *qen;
2477725ccfdSJing Huang 
2487725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2497725ccfdSJing Huang 	bfa_trc(port->fcs, event);
2507725ccfdSJing Huang 
2517725ccfdSJing Huang 	switch (event) {
2527725ccfdSJing Huang 	case BFA_FCS_PORT_SM_ONLINE:
253a36c61f9SKrishna Gudipati 		bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
254a36c61f9SKrishna Gudipati 		bfa_fcs_lport_online_actions(port);
2557725ccfdSJing Huang 		break;
2567725ccfdSJing Huang 
257dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_STOP:
258dd5aaf45SKrishna Gudipati 		if (port->num_rports == 0) {
259dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
260dd5aaf45SKrishna Gudipati 			/* If vport - send completion call back */
261dd5aaf45SKrishna Gudipati 			if (port->vport)
262dd5aaf45SKrishna Gudipati 				bfa_fcs_vport_stop_comp(port->vport);
263881c1b3cSKrishna Gudipati 			else
264881c1b3cSKrishna Gudipati 				bfa_wc_down(&(port->fabric->stop_wc));
265dd5aaf45SKrishna Gudipati 		} else {
266dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
267dd5aaf45SKrishna Gudipati 			list_for_each_safe(qe, qen, &port->rport_q) {
268dd5aaf45SKrishna Gudipati 				rport = (struct bfa_fcs_rport_s *) qe;
269dd5aaf45SKrishna Gudipati 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
270dd5aaf45SKrishna Gudipati 			}
271dd5aaf45SKrishna Gudipati 		}
272dd5aaf45SKrishna Gudipati 		break;
273dd5aaf45SKrishna Gudipati 
2747725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELETE:
2757725ccfdSJing Huang 		if (port->num_rports == 0) {
276a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
277a36c61f9SKrishna Gudipati 			bfa_fcs_lport_deleted(port);
2787725ccfdSJing Huang 		} else {
279a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
2807725ccfdSJing Huang 			list_for_each_safe(qe, qen, &port->rport_q) {
2817725ccfdSJing Huang 				rport = (struct bfa_fcs_rport_s *) qe;
282f7f73812SMaggie Zhang 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
2837725ccfdSJing Huang 			}
2847725ccfdSJing Huang 		}
2857725ccfdSJing Huang 		break;
2867725ccfdSJing Huang 
2877725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELRPORT:
2887725ccfdSJing Huang 	case BFA_FCS_PORT_SM_OFFLINE:
2897725ccfdSJing Huang 		break;
2907725ccfdSJing Huang 
2917725ccfdSJing Huang 	default:
292e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
2937725ccfdSJing Huang 	}
2947725ccfdSJing Huang }
2957725ccfdSJing Huang 
2967725ccfdSJing Huang static void
297dd5aaf45SKrishna Gudipati bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
298dd5aaf45SKrishna Gudipati 			  enum bfa_fcs_lport_event event)
299dd5aaf45SKrishna Gudipati {
300dd5aaf45SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
301dd5aaf45SKrishna Gudipati 	bfa_trc(port->fcs, event);
302dd5aaf45SKrishna Gudipati 
303dd5aaf45SKrishna Gudipati 	switch (event) {
304dd5aaf45SKrishna Gudipati 	case BFA_FCS_PORT_SM_DELRPORT:
305dd5aaf45SKrishna Gudipati 		if (port->num_rports == 0) {
306dd5aaf45SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
307dd5aaf45SKrishna Gudipati 			/* If vport - send completion call back */
308dd5aaf45SKrishna Gudipati 			if (port->vport)
309dd5aaf45SKrishna Gudipati 				bfa_fcs_vport_stop_comp(port->vport);
310881c1b3cSKrishna Gudipati 			else
311881c1b3cSKrishna Gudipati 				bfa_wc_down(&(port->fabric->stop_wc));
312dd5aaf45SKrishna Gudipati 		}
313dd5aaf45SKrishna Gudipati 		break;
314dd5aaf45SKrishna Gudipati 
315dd5aaf45SKrishna Gudipati 	default:
316dd5aaf45SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
317dd5aaf45SKrishna Gudipati 	}
318dd5aaf45SKrishna Gudipati }
319dd5aaf45SKrishna Gudipati 
320dd5aaf45SKrishna Gudipati static void
321a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_deleting(
322a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
323a36c61f9SKrishna Gudipati 	enum bfa_fcs_lport_event event)
3247725ccfdSJing Huang {
3257725ccfdSJing Huang 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3267725ccfdSJing Huang 	bfa_trc(port->fcs, event);
3277725ccfdSJing Huang 
3287725ccfdSJing Huang 	switch (event) {
3297725ccfdSJing Huang 	case BFA_FCS_PORT_SM_DELRPORT:
3307725ccfdSJing Huang 		if (port->num_rports == 0) {
331a36c61f9SKrishna Gudipati 			bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
332a36c61f9SKrishna Gudipati 			bfa_fcs_lport_deleted(port);
3337725ccfdSJing Huang 		}
3347725ccfdSJing Huang 		break;
3357725ccfdSJing Huang 
3367725ccfdSJing Huang 	default:
337e641de37SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
3387725ccfdSJing Huang 	}
3397725ccfdSJing Huang }
3407725ccfdSJing Huang 
3415fbe25c7SJing Huang /*
3427725ccfdSJing Huang  *  fcs_port_pvt
3437725ccfdSJing Huang  */
3447725ccfdSJing Huang 
3457725ccfdSJing Huang /*
3467826f304SKrishna Gudipati  * Send AEN notification
3477826f304SKrishna Gudipati  */
3487826f304SKrishna Gudipati static void
3497826f304SKrishna Gudipati bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port,
3507826f304SKrishna Gudipati 			enum bfa_lport_aen_event event)
3517826f304SKrishna Gudipati {
3527826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
3537826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
3547826f304SKrishna Gudipati 
3557826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
3567826f304SKrishna Gudipati 	if (!aen_entry)
3577826f304SKrishna Gudipati 		return;
3587826f304SKrishna Gudipati 
3597826f304SKrishna Gudipati 	aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
3607826f304SKrishna Gudipati 	aen_entry->aen_data.lport.roles = port->port_cfg.roles;
3617826f304SKrishna Gudipati 	aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
3627826f304SKrishna Gudipati 					bfa_fcs_get_base_port(port->fcs));
3637826f304SKrishna Gudipati 	aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
3647826f304SKrishna Gudipati 
3657826f304SKrishna Gudipati 	/* Send the AEN notification */
3667826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
3677826f304SKrishna Gudipati 				  BFA_AEN_CAT_LPORT, event);
3687826f304SKrishna Gudipati }
3697826f304SKrishna Gudipati 
3707826f304SKrishna Gudipati /*
3717725ccfdSJing Huang  * Send a LS reject
3727725ccfdSJing Huang  */
3737725ccfdSJing Huang static void
374a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
3757725ccfdSJing Huang 			 u8 reason_code, u8 reason_code_expl)
3767725ccfdSJing Huang {
3777725ccfdSJing Huang 	struct fchs_s	fchs;
3787725ccfdSJing Huang 	struct bfa_fcxp_s *fcxp;
3797725ccfdSJing Huang 	struct bfa_rport_s *bfa_rport = NULL;
3807725ccfdSJing Huang 	int		len;
3817725ccfdSJing Huang 
382a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
3837725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
3847725ccfdSJing Huang 
385c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
3867725ccfdSJing Huang 	if (!fcxp)
3877725ccfdSJing Huang 		return;
3887725ccfdSJing Huang 
389a36c61f9SKrishna Gudipati 	len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
390a36c61f9SKrishna Gudipati 			      rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
391a36c61f9SKrishna Gudipati 			      rx_fchs->ox_id, reason_code, reason_code_expl);
3927725ccfdSJing Huang 
3937725ccfdSJing Huang 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
3947725ccfdSJing Huang 			  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
3957725ccfdSJing Huang 			  FC_MAX_PDUSZ, 0);
3967725ccfdSJing Huang }
3977725ccfdSJing Huang 
3985fbe25c7SJing Huang /*
399d7be54ccSKrishna Gudipati  * Send a FCCT Reject
400d7be54ccSKrishna Gudipati  */
401d7be54ccSKrishna Gudipati static void
402d7be54ccSKrishna Gudipati bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port,
403d7be54ccSKrishna Gudipati 	struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl)
404d7be54ccSKrishna Gudipati {
405d7be54ccSKrishna Gudipati 	struct fchs_s   fchs;
406d7be54ccSKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
407d7be54ccSKrishna Gudipati 	struct bfa_rport_s *bfa_rport = NULL;
408d7be54ccSKrishna Gudipati 	int             len;
409d7be54ccSKrishna Gudipati 	struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1);
410d7be54ccSKrishna Gudipati 	struct ct_hdr_s *ct_hdr;
411d7be54ccSKrishna Gudipati 
412d7be54ccSKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
413d7be54ccSKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
414d7be54ccSKrishna Gudipati 
415c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
416d7be54ccSKrishna Gudipati 	if (!fcxp)
417d7be54ccSKrishna Gudipati 		return;
418d7be54ccSKrishna Gudipati 
419d7be54ccSKrishna Gudipati 	ct_hdr = bfa_fcxp_get_reqbuf(fcxp);
420d7be54ccSKrishna Gudipati 	ct_hdr->gs_type = rx_cthdr->gs_type;
421d7be54ccSKrishna Gudipati 	ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type;
422d7be54ccSKrishna Gudipati 
423d7be54ccSKrishna Gudipati 	len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id,
424d7be54ccSKrishna Gudipati 			bfa_fcs_lport_get_fcid(port),
425d7be54ccSKrishna Gudipati 			rx_fchs->ox_id, reason_code, reason_code_expl);
426d7be54ccSKrishna Gudipati 
427d7be54ccSKrishna Gudipati 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
428d7be54ccSKrishna Gudipati 			BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
429d7be54ccSKrishna Gudipati 			FC_MAX_PDUSZ, 0);
430d7be54ccSKrishna Gudipati }
431d7be54ccSKrishna Gudipati 
432d7be54ccSKrishna Gudipati /*
4337725ccfdSJing Huang  * Process incoming plogi from a remote port.
4347725ccfdSJing Huang  */
4357725ccfdSJing Huang static void
436a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
437a36c61f9SKrishna Gudipati 		struct fchs_s *rx_fchs, struct fc_logi_s *plogi)
4387725ccfdSJing Huang {
4397725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
4407725ccfdSJing Huang 
4417725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->d_id);
4427725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
4437725ccfdSJing Huang 
4447725ccfdSJing Huang 	/*
4457725ccfdSJing Huang 	 * If min cfg mode is enabled, drop any incoming PLOGIs
4467725ccfdSJing Huang 	 */
4477725ccfdSJing Huang 	if (__fcs_min_cfg(port->fcs)) {
4487725ccfdSJing Huang 		bfa_trc(port->fcs, rx_fchs->s_id);
4497725ccfdSJing Huang 		return;
4507725ccfdSJing Huang 	}
4517725ccfdSJing Huang 
4527725ccfdSJing Huang 	if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
4537725ccfdSJing Huang 		bfa_trc(port->fcs, rx_fchs->s_id);
4547725ccfdSJing Huang 		/*
4557725ccfdSJing Huang 		 * send a LS reject
4567725ccfdSJing Huang 		 */
457a36c61f9SKrishna Gudipati 		bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
4587725ccfdSJing Huang 					FC_LS_RJT_RSN_PROTOCOL_ERROR,
4597725ccfdSJing Huang 					FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS);
4607725ccfdSJing Huang 		return;
4617725ccfdSJing Huang 	}
4627725ccfdSJing Huang 
4635fbe25c7SJing Huang 	/*
4647725ccfdSJing Huang 	 * Direct Attach P2P mode : verify address assigned by the r-port.
4657725ccfdSJing Huang 	 */
466a36c61f9SKrishna Gudipati 	if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
467a36c61f9SKrishna Gudipati 		(memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
468a36c61f9SKrishna Gudipati 			   (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
4697725ccfdSJing Huang 		if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
470a36c61f9SKrishna Gudipati 			/* Address assigned to us cannot be a WKA */
471a36c61f9SKrishna Gudipati 			bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
4727725ccfdSJing Huang 					FC_LS_RJT_RSN_PROTOCOL_ERROR,
4737725ccfdSJing Huang 					FC_LS_RJT_EXP_INVALID_NPORT_ID);
4747725ccfdSJing Huang 			return;
4757725ccfdSJing Huang 		}
4767725ccfdSJing Huang 		port->pid  = rx_fchs->d_id;
477b704495cSKrishna Gudipati 		bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
4787725ccfdSJing Huang 	}
4797725ccfdSJing Huang 
4805fbe25c7SJing Huang 	/*
4817725ccfdSJing Huang 	 * First, check if we know the device by pwwn.
4827725ccfdSJing Huang 	 */
483a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name);
4847725ccfdSJing Huang 	if (rport) {
4855fbe25c7SJing Huang 		/*
486a36c61f9SKrishna Gudipati 		 * Direct Attach P2P mode : handle address assigned by r-port.
4877725ccfdSJing Huang 		 */
488a36c61f9SKrishna Gudipati 		if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
489a36c61f9SKrishna Gudipati 			(memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
4907725ccfdSJing Huang 			(void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
4917725ccfdSJing Huang 			port->pid  = rx_fchs->d_id;
492b704495cSKrishna Gudipati 			bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
4937725ccfdSJing Huang 			rport->pid = rx_fchs->s_id;
4947725ccfdSJing Huang 		}
4957725ccfdSJing Huang 		bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
4967725ccfdSJing Huang 		return;
4977725ccfdSJing Huang 	}
4987725ccfdSJing Huang 
4995fbe25c7SJing Huang 	/*
5007725ccfdSJing Huang 	 * Next, lookup rport by PID.
5017725ccfdSJing Huang 	 */
502a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id);
5037725ccfdSJing Huang 	if (!rport) {
5045fbe25c7SJing Huang 		/*
5057725ccfdSJing Huang 		 * Inbound PLOGI from a new device.
5067725ccfdSJing Huang 		 */
5077725ccfdSJing Huang 		bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
5087725ccfdSJing Huang 		return;
5097725ccfdSJing Huang 	}
5107725ccfdSJing Huang 
5115fbe25c7SJing Huang 	/*
5127725ccfdSJing Huang 	 * Rport is known only by PID.
5137725ccfdSJing Huang 	 */
5147725ccfdSJing Huang 	if (rport->pwwn) {
5155fbe25c7SJing Huang 		/*
5167725ccfdSJing Huang 		 * This is a different device with the same pid. Old device
5177725ccfdSJing Huang 		 * disappeared. Send implicit LOGO to old device.
5187725ccfdSJing Huang 		 */
519d4b671c5SJing Huang 		WARN_ON(rport->pwwn == plogi->port_name);
520f7f73812SMaggie Zhang 		bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
5217725ccfdSJing Huang 
5225fbe25c7SJing Huang 		/*
5237725ccfdSJing Huang 		 * Inbound PLOGI from a new device (with old PID).
5247725ccfdSJing Huang 		 */
5257725ccfdSJing Huang 		bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
5267725ccfdSJing Huang 		return;
5277725ccfdSJing Huang 	}
5287725ccfdSJing Huang 
5295fbe25c7SJing Huang 	/*
5307725ccfdSJing Huang 	 * PLOGI crossing each other.
5317725ccfdSJing Huang 	 */
532d4b671c5SJing Huang 	WARN_ON(rport->pwwn != WWN_NULL);
5337725ccfdSJing Huang 	bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
5347725ccfdSJing Huang }
5357725ccfdSJing Huang 
5367725ccfdSJing Huang /*
5377725ccfdSJing Huang  * Process incoming ECHO.
5387725ccfdSJing Huang  * Since it does not require a login, it is processed here.
5397725ccfdSJing Huang  */
5407725ccfdSJing Huang static void
541a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
5427725ccfdSJing Huang 		struct fc_echo_s *echo, u16 rx_len)
5437725ccfdSJing Huang {
5447725ccfdSJing Huang 	struct fchs_s		fchs;
5457725ccfdSJing Huang 	struct bfa_fcxp_s	*fcxp;
5467725ccfdSJing Huang 	struct bfa_rport_s	*bfa_rport = NULL;
5477725ccfdSJing Huang 	int			len, pyld_len;
5487725ccfdSJing Huang 
5497725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
5507725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->d_id);
5517725ccfdSJing Huang 
552c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
5537725ccfdSJing Huang 	if (!fcxp)
5547725ccfdSJing Huang 		return;
5557725ccfdSJing Huang 
556a36c61f9SKrishna Gudipati 	len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
557a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
558a36c61f9SKrishna Gudipati 				rx_fchs->ox_id);
5597725ccfdSJing Huang 
5607725ccfdSJing Huang 	/*
5617725ccfdSJing Huang 	 * Copy the payload (if any) from the echo frame
5627725ccfdSJing Huang 	 */
5637725ccfdSJing Huang 	pyld_len = rx_len - sizeof(struct fchs_s);
564a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_len);
5657725ccfdSJing Huang 	bfa_trc(port->fcs, pyld_len);
5667725ccfdSJing Huang 
5677725ccfdSJing Huang 	if (pyld_len > len)
5687725ccfdSJing Huang 		memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
5697725ccfdSJing Huang 			sizeof(struct fc_echo_s), (echo + 1),
5707725ccfdSJing Huang 			(pyld_len - sizeof(struct fc_echo_s)));
5717725ccfdSJing Huang 
5727725ccfdSJing Huang 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
5737725ccfdSJing Huang 			BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
5747725ccfdSJing Huang 			FC_MAX_PDUSZ, 0);
5757725ccfdSJing Huang }
5767725ccfdSJing Huang 
5777725ccfdSJing Huang /*
5787725ccfdSJing Huang  * Process incoming RNID.
5797725ccfdSJing Huang  * Since it does not require a login, it is processed here.
5807725ccfdSJing Huang  */
5817725ccfdSJing Huang static void
582a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
5837725ccfdSJing Huang 		struct fc_rnid_cmd_s *rnid, u16 rx_len)
5847725ccfdSJing Huang {
5857725ccfdSJing Huang 	struct fc_rnid_common_id_data_s common_id_data;
5867725ccfdSJing Huang 	struct fc_rnid_general_topology_data_s gen_topo_data;
5877725ccfdSJing Huang 	struct fchs_s	fchs;
5887725ccfdSJing Huang 	struct bfa_fcxp_s *fcxp;
5897725ccfdSJing Huang 	struct bfa_rport_s *bfa_rport = NULL;
5907725ccfdSJing Huang 	u16	len;
5917725ccfdSJing Huang 	u32	data_format;
5927725ccfdSJing Huang 
5937725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->s_id);
5947725ccfdSJing Huang 	bfa_trc(port->fcs, rx_fchs->d_id);
5957725ccfdSJing Huang 	bfa_trc(port->fcs, rx_len);
5967725ccfdSJing Huang 
597c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
5987725ccfdSJing Huang 	if (!fcxp)
5997725ccfdSJing Huang 		return;
6007725ccfdSJing Huang 
6017725ccfdSJing Huang 	/*
6027725ccfdSJing Huang 	 * Check Node Indentification Data Format
6037725ccfdSJing Huang 	 * We only support General Topology Discovery Format.
6047725ccfdSJing Huang 	 * For any other requested Data Formats, we return Common Node Id Data
6057725ccfdSJing Huang 	 * only, as per FC-LS.
6067725ccfdSJing Huang 	 */
6077725ccfdSJing Huang 	bfa_trc(port->fcs, rnid->node_id_data_format);
6087725ccfdSJing Huang 	if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
6097725ccfdSJing Huang 		data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
6107725ccfdSJing Huang 		/*
6117725ccfdSJing Huang 		 * Get General topology data for this port
6127725ccfdSJing Huang 		 */
6137725ccfdSJing Huang 		bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
6147725ccfdSJing Huang 	} else {
6157725ccfdSJing Huang 		data_format = RNID_NODEID_DATA_FORMAT_COMMON;
6167725ccfdSJing Huang 	}
6177725ccfdSJing Huang 
6187725ccfdSJing Huang 	/*
6197725ccfdSJing Huang 	 * Copy the Node Id Info
6207725ccfdSJing Huang 	 */
621a36c61f9SKrishna Gudipati 	common_id_data.port_name = bfa_fcs_lport_get_pwwn(port);
622a36c61f9SKrishna Gudipati 	common_id_data.node_name = bfa_fcs_lport_get_nwwn(port);
6237725ccfdSJing Huang 
624a36c61f9SKrishna Gudipati 	len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
625a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
626a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, data_format, &common_id_data,
627a36c61f9SKrishna Gudipati 				&gen_topo_data);
6287725ccfdSJing Huang 
6297725ccfdSJing Huang 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
6307725ccfdSJing Huang 			BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
6317725ccfdSJing Huang 			FC_MAX_PDUSZ, 0);
6327725ccfdSJing Huang }
6337725ccfdSJing Huang 
6347725ccfdSJing Huang /*
6357725ccfdSJing Huang  *  Fill out General Topolpgy Discovery Data for RNID ELS.
6367725ccfdSJing Huang  */
6377725ccfdSJing Huang static void
638a36c61f9SKrishna Gudipati bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
6397725ccfdSJing Huang 			struct fc_rnid_general_topology_data_s *gen_topo_data)
6407725ccfdSJing Huang {
6416a18b167SJing Huang 	memset(gen_topo_data, 0,
6427725ccfdSJing Huang 		      sizeof(struct fc_rnid_general_topology_data_s));
6437725ccfdSJing Huang 
644ba816ea8SJing Huang 	gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST);
6457725ccfdSJing Huang 	gen_topo_data->phy_port_num = 0;	/* @todo */
646ba816ea8SJing Huang 	gen_topo_data->num_attached_nodes = cpu_to_be32(1);
6477725ccfdSJing Huang }
6487725ccfdSJing Huang 
6497725ccfdSJing Huang static void
650a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
6517725ccfdSJing Huang {
652a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
653a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
654a36c61f9SKrishna Gudipati 
6557725ccfdSJing Huang 	bfa_trc(port->fcs, port->fabric->oper_type);
6567725ccfdSJing Huang 
6577725ccfdSJing Huang 	__port_action[port->fabric->fab_type].init(port);
6587725ccfdSJing Huang 	__port_action[port->fabric->fab_type].online(port);
6597725ccfdSJing Huang 
660a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
661a3f29cccSKrishna Gudipati 	BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
662a36c61f9SKrishna Gudipati 		"Logical port online: WWN = %s Role = %s\n",
663a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
6647826f304SKrishna Gudipati 	bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE);
665a36c61f9SKrishna Gudipati 
666a36c61f9SKrishna Gudipati 	bfad->bfad_flags |= BFAD_PORT_ONLINE;
6677725ccfdSJing Huang }
6687725ccfdSJing Huang 
6697725ccfdSJing Huang static void
670a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
6717725ccfdSJing Huang {
6727725ccfdSJing Huang 	struct list_head	*qe, *qen;
6737725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
674a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
675a36c61f9SKrishna Gudipati 	char    lpwwn_buf[BFA_STRING_32];
6767725ccfdSJing Huang 
6777725ccfdSJing Huang 	bfa_trc(port->fcs, port->fabric->oper_type);
6787725ccfdSJing Huang 
6797725ccfdSJing Huang 	__port_action[port->fabric->fab_type].offline(port);
6807725ccfdSJing Huang 
681a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
682f7f73812SMaggie Zhang 	if (bfa_sm_cmp_state(port->fabric,
6837826f304SKrishna Gudipati 			bfa_fcs_fabric_sm_online) == BFA_TRUE) {
684a3f29cccSKrishna Gudipati 		BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
685a36c61f9SKrishna Gudipati 		"Logical port lost fabric connectivity: WWN = %s Role = %s\n",
686a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
6877826f304SKrishna Gudipati 		bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
6887826f304SKrishna Gudipati 	} else {
689a3f29cccSKrishna Gudipati 		BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
690a36c61f9SKrishna Gudipati 		"Logical port taken offline: WWN = %s Role = %s\n",
691a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
6927826f304SKrishna Gudipati 		bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE);
6937826f304SKrishna Gudipati 	}
6947725ccfdSJing Huang 
6957725ccfdSJing Huang 	list_for_each_safe(qe, qen, &port->rport_q) {
6967725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
697f7f73812SMaggie Zhang 		bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
6987725ccfdSJing Huang 	}
6997725ccfdSJing Huang }
7007725ccfdSJing Huang 
7017725ccfdSJing Huang static void
702a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port)
7037725ccfdSJing Huang {
704d4b671c5SJing Huang 	WARN_ON(1);
7057725ccfdSJing Huang }
7067725ccfdSJing Huang 
7077725ccfdSJing Huang static void
708a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port)
7097725ccfdSJing Huang {
710d4b671c5SJing Huang 	WARN_ON(1);
7117725ccfdSJing Huang }
7127725ccfdSJing Huang 
7137725ccfdSJing Huang static void
714a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port)
7157725ccfdSJing Huang {
716d4b671c5SJing Huang 	WARN_ON(1);
7177725ccfdSJing Huang }
7187725ccfdSJing Huang 
7197725ccfdSJing Huang static void
720a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs)
7217725ccfdSJing Huang {
722a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
723a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
724a36c61f9SKrishna Gudipati 	int		len;
7257725ccfdSJing Huang 
726a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
727a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
728a36c61f9SKrishna Gudipati 
729c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
730a36c61f9SKrishna Gudipati 	if (!fcxp)
731a36c61f9SKrishna Gudipati 		return;
732a36c61f9SKrishna Gudipati 
733a36c61f9SKrishna Gudipati 	len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
734a36c61f9SKrishna Gudipati 			rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
735a36c61f9SKrishna Gudipati 			rx_fchs->ox_id, 0);
736a36c61f9SKrishna Gudipati 
737a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
738a36c61f9SKrishna Gudipati 			  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
739a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, 0);
740a36c61f9SKrishna Gudipati }
741a36c61f9SKrishna Gudipati static void
742a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
743a36c61f9SKrishna Gudipati {
744a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
745a36c61f9SKrishna Gudipati 	char    lpwwn_buf[BFA_STRING_32];
746a36c61f9SKrishna Gudipati 
747a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
74888166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
749a36c61f9SKrishna Gudipati 		"Logical port deleted: WWN = %s Role = %s\n",
750a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
7517826f304SKrishna Gudipati 	bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE);
752a36c61f9SKrishna Gudipati 
753a36c61f9SKrishna Gudipati 	/* Base port will be deleted by the OS driver */
75417c201b3SKrishna Gudipati 	if (port->vport)
7557725ccfdSJing Huang 		bfa_fcs_vport_delete_comp(port->vport);
75617c201b3SKrishna Gudipati 	else
757f7f73812SMaggie Zhang 		bfa_wc_down(&port->fabric->wc);
7587725ccfdSJing Huang }
7597725ccfdSJing Huang 
7607725ccfdSJing Huang 
7615fbe25c7SJing Huang /*
7627725ccfdSJing Huang  * Unsolicited frame receive handling.
7637725ccfdSJing Huang  */
7647725ccfdSJing Huang void
765a36c61f9SKrishna Gudipati bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
766a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
7677725ccfdSJing Huang {
7687725ccfdSJing Huang 	u32	pid = fchs->s_id;
7697725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport = NULL;
7707725ccfdSJing Huang 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
7717725ccfdSJing Huang 
7727725ccfdSJing Huang 	bfa_stats(lport, uf_recvs);
77315821f05SKrishna Gudipati 	bfa_trc(lport->fcs, fchs->type);
7747725ccfdSJing Huang 
775a36c61f9SKrishna Gudipati 	if (!bfa_fcs_lport_is_online(lport)) {
7767725ccfdSJing Huang 		bfa_stats(lport, uf_recv_drops);
7777725ccfdSJing Huang 		return;
7787725ccfdSJing Huang 	}
7797725ccfdSJing Huang 
7805fbe25c7SJing Huang 	/*
7817725ccfdSJing Huang 	 * First, handle ELSs that donot require a login.
7827725ccfdSJing Huang 	 */
7837725ccfdSJing Huang 	/*
7847725ccfdSJing Huang 	 * Handle PLOGI first
7857725ccfdSJing Huang 	 */
7867725ccfdSJing Huang 	if ((fchs->type == FC_TYPE_ELS) &&
7877725ccfdSJing Huang 		(els_cmd->els_code == FC_ELS_PLOGI)) {
788a36c61f9SKrishna Gudipati 		bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
7897725ccfdSJing Huang 		return;
7907725ccfdSJing Huang 	}
7917725ccfdSJing Huang 
7927725ccfdSJing Huang 	/*
7937725ccfdSJing Huang 	 * Handle ECHO separately.
7947725ccfdSJing Huang 	 */
7957725ccfdSJing Huang 	if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
796a36c61f9SKrishna Gudipati 		bfa_fcs_lport_echo(lport, fchs,
7977725ccfdSJing Huang 				(struct fc_echo_s *)els_cmd, len);
7987725ccfdSJing Huang 		return;
7997725ccfdSJing Huang 	}
8007725ccfdSJing Huang 
8017725ccfdSJing Huang 	/*
8027725ccfdSJing Huang 	 * Handle RNID separately.
8037725ccfdSJing Huang 	 */
8047725ccfdSJing Huang 	if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
805a36c61f9SKrishna Gudipati 		bfa_fcs_lport_rnid(lport, fchs,
8067725ccfdSJing Huang 			(struct fc_rnid_cmd_s *) els_cmd, len);
8077725ccfdSJing Huang 		return;
8087725ccfdSJing Huang 	}
8097725ccfdSJing Huang 
810a36c61f9SKrishna Gudipati 	if (fchs->type == FC_TYPE_BLS) {
811a36c61f9SKrishna Gudipati 		if ((fchs->routing == FC_RTG_BASIC_LINK) &&
812a36c61f9SKrishna Gudipati 				(fchs->cat_info == FC_CAT_ABTS))
813a36c61f9SKrishna Gudipati 			bfa_fcs_lport_abts_acc(lport, fchs);
814a36c61f9SKrishna Gudipati 		return;
815a36c61f9SKrishna Gudipati 	}
816d7be54ccSKrishna Gudipati 
817d7be54ccSKrishna Gudipati 	if (fchs->type == FC_TYPE_SERVICES) {
818d7be54ccSKrishna Gudipati 		/*
819d7be54ccSKrishna Gudipati 		 * Unhandled FC-GS frames. Send a FC-CT Reject
820d7be54ccSKrishna Gudipati 		 */
821d7be54ccSKrishna Gudipati 		bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP,
822d7be54ccSKrishna Gudipati 				CT_NS_EXP_NOADDITIONAL);
823d7be54ccSKrishna Gudipati 		return;
824d7be54ccSKrishna Gudipati 	}
825d7be54ccSKrishna Gudipati 
8265fbe25c7SJing Huang 	/*
8277725ccfdSJing Huang 	 * look for a matching remote port ID
8287725ccfdSJing Huang 	 */
829a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pid(lport, pid);
8307725ccfdSJing Huang 	if (rport) {
8317725ccfdSJing Huang 		bfa_trc(rport->fcs, fchs->s_id);
8327725ccfdSJing Huang 		bfa_trc(rport->fcs, fchs->d_id);
8337725ccfdSJing Huang 		bfa_trc(rport->fcs, fchs->type);
8347725ccfdSJing Huang 
8357725ccfdSJing Huang 		bfa_fcs_rport_uf_recv(rport, fchs, len);
8367725ccfdSJing Huang 		return;
8377725ccfdSJing Huang 	}
8387725ccfdSJing Huang 
8395fbe25c7SJing Huang 	/*
8407725ccfdSJing Huang 	 * Only handles ELS frames for now.
8417725ccfdSJing Huang 	 */
8427725ccfdSJing Huang 	if (fchs->type != FC_TYPE_ELS) {
84315821f05SKrishna Gudipati 		bfa_trc(lport->fcs, fchs->s_id);
84415821f05SKrishna Gudipati 		bfa_trc(lport->fcs, fchs->d_id);
84515821f05SKrishna Gudipati 		/* ignore type FC_TYPE_FC_FSS */
84615821f05SKrishna Gudipati 		if (fchs->type != FC_TYPE_FC_FSS)
84715821f05SKrishna Gudipati 			bfa_sm_fault(lport->fcs, fchs->type);
8487725ccfdSJing Huang 		return;
8497725ccfdSJing Huang 	}
8507725ccfdSJing Huang 
8517725ccfdSJing Huang 	bfa_trc(lport->fcs, els_cmd->els_code);
8527725ccfdSJing Huang 	if (els_cmd->els_code == FC_ELS_RSCN) {
853a36c61f9SKrishna Gudipati 		bfa_fcs_lport_scn_process_rscn(lport, fchs, len);
8547725ccfdSJing Huang 		return;
8557725ccfdSJing Huang 	}
8567725ccfdSJing Huang 
8577725ccfdSJing Huang 	if (els_cmd->els_code == FC_ELS_LOGO) {
8585fbe25c7SJing Huang 		/*
8597725ccfdSJing Huang 		 * @todo Handle LOGO frames received.
8607725ccfdSJing Huang 		 */
8617725ccfdSJing Huang 		return;
8627725ccfdSJing Huang 	}
8637725ccfdSJing Huang 
8647725ccfdSJing Huang 	if (els_cmd->els_code == FC_ELS_PRLI) {
8655fbe25c7SJing Huang 		/*
8667725ccfdSJing Huang 		 * @todo Handle PRLI frames received.
8677725ccfdSJing Huang 		 */
8687725ccfdSJing Huang 		return;
8697725ccfdSJing Huang 	}
8707725ccfdSJing Huang 
8715fbe25c7SJing Huang 	/*
8727725ccfdSJing Huang 	 * Unhandled ELS frames. Send a LS_RJT.
8737725ccfdSJing Huang 	 */
874a36c61f9SKrishna Gudipati 	bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
8757725ccfdSJing Huang 				 FC_LS_RJT_EXP_NO_ADDL_INFO);
8767725ccfdSJing Huang 
8777725ccfdSJing Huang }
8787725ccfdSJing Huang 
8795fbe25c7SJing Huang /*
8807725ccfdSJing Huang  *   PID based Lookup for a R-Port in the Port R-Port Queue
8817725ccfdSJing Huang  */
8827725ccfdSJing Huang struct bfa_fcs_rport_s *
883a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid)
8847725ccfdSJing Huang {
8857725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
8867725ccfdSJing Huang 	struct list_head	*qe;
8877725ccfdSJing Huang 
8887725ccfdSJing Huang 	list_for_each(qe, &port->rport_q) {
8897725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
8907725ccfdSJing Huang 		if (rport->pid == pid)
8917725ccfdSJing Huang 			return rport;
8927725ccfdSJing Huang 	}
8937725ccfdSJing Huang 
8947725ccfdSJing Huang 	bfa_trc(port->fcs, pid);
8957725ccfdSJing Huang 	return NULL;
8967725ccfdSJing Huang }
8977725ccfdSJing Huang 
8985fbe25c7SJing Huang /*
899ee1a4a42SKrishna Gudipati  * OLD_PID based Lookup for a R-Port in the Port R-Port Queue
900ee1a4a42SKrishna Gudipati  */
901ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s *
902ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_by_old_pid(struct bfa_fcs_lport_s *port, u32 pid)
903ee1a4a42SKrishna Gudipati {
904ee1a4a42SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
905ee1a4a42SKrishna Gudipati 	struct list_head	*qe;
906ee1a4a42SKrishna Gudipati 
907ee1a4a42SKrishna Gudipati 	list_for_each(qe, &port->rport_q) {
908ee1a4a42SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
909ee1a4a42SKrishna Gudipati 		if (rport->old_pid == pid)
910ee1a4a42SKrishna Gudipati 			return rport;
911ee1a4a42SKrishna Gudipati 	}
912ee1a4a42SKrishna Gudipati 
913ee1a4a42SKrishna Gudipati 	bfa_trc(port->fcs, pid);
914ee1a4a42SKrishna Gudipati 	return NULL;
915ee1a4a42SKrishna Gudipati }
916ee1a4a42SKrishna Gudipati 
917ee1a4a42SKrishna Gudipati /*
9187725ccfdSJing Huang  *   PWWN based Lookup for a R-Port in the Port R-Port Queue
9197725ccfdSJing Huang  */
9207725ccfdSJing Huang struct bfa_fcs_rport_s *
921a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn)
9227725ccfdSJing Huang {
9237725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
9247725ccfdSJing Huang 	struct list_head	*qe;
9257725ccfdSJing Huang 
9267725ccfdSJing Huang 	list_for_each(qe, &port->rport_q) {
9277725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
9287725ccfdSJing Huang 		if (wwn_is_equal(rport->pwwn, pwwn))
9297725ccfdSJing Huang 			return rport;
9307725ccfdSJing Huang 	}
9317725ccfdSJing Huang 
9327725ccfdSJing Huang 	bfa_trc(port->fcs, pwwn);
933f8ceafdeSJing Huang 	return NULL;
9347725ccfdSJing Huang }
9357725ccfdSJing Huang 
9365fbe25c7SJing Huang /*
9377725ccfdSJing Huang  *   NWWN based Lookup for a R-Port in the Port R-Port Queue
9387725ccfdSJing Huang  */
9397725ccfdSJing Huang struct bfa_fcs_rport_s *
940a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn)
9417725ccfdSJing Huang {
9427725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport;
9437725ccfdSJing Huang 	struct list_head	*qe;
9447725ccfdSJing Huang 
9457725ccfdSJing Huang 	list_for_each(qe, &port->rport_q) {
9467725ccfdSJing Huang 		rport = (struct bfa_fcs_rport_s *) qe;
9477725ccfdSJing Huang 		if (wwn_is_equal(rport->nwwn, nwwn))
9487725ccfdSJing Huang 			return rport;
9497725ccfdSJing Huang 	}
9507725ccfdSJing Huang 
9517725ccfdSJing Huang 	bfa_trc(port->fcs, nwwn);
952f8ceafdeSJing Huang 	return NULL;
9537725ccfdSJing Huang }
9547725ccfdSJing Huang 
9555fbe25c7SJing Huang /*
956ee1a4a42SKrishna Gudipati  * PWWN & PID based Lookup for a R-Port in the Port R-Port Queue
957ee1a4a42SKrishna Gudipati  */
958ee1a4a42SKrishna Gudipati struct bfa_fcs_rport_s *
959ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_by_qualifier(struct bfa_fcs_lport_s *port,
960ee1a4a42SKrishna Gudipati 				     wwn_t pwwn, u32 pid)
961ee1a4a42SKrishna Gudipati {
962ee1a4a42SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
963ee1a4a42SKrishna Gudipati 	struct list_head	*qe;
964ee1a4a42SKrishna Gudipati 
965ee1a4a42SKrishna Gudipati 	list_for_each(qe, &port->rport_q) {
966ee1a4a42SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
967ee1a4a42SKrishna Gudipati 		if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid)
968ee1a4a42SKrishna Gudipati 			return rport;
969ee1a4a42SKrishna Gudipati 	}
970ee1a4a42SKrishna Gudipati 
971ee1a4a42SKrishna Gudipati 	bfa_trc(port->fcs, pwwn);
972ee1a4a42SKrishna Gudipati 	return NULL;
973ee1a4a42SKrishna Gudipati }
974ee1a4a42SKrishna Gudipati 
975ee1a4a42SKrishna Gudipati /*
9767725ccfdSJing Huang  * Called by rport module when new rports are discovered.
9777725ccfdSJing Huang  */
9787725ccfdSJing Huang void
979a36c61f9SKrishna Gudipati bfa_fcs_lport_add_rport(
980a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
9817725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport)
9827725ccfdSJing Huang {
9837725ccfdSJing Huang 	list_add_tail(&rport->qe, &port->rport_q);
9847725ccfdSJing Huang 	port->num_rports++;
9857725ccfdSJing Huang }
9867725ccfdSJing Huang 
9875fbe25c7SJing Huang /*
9887725ccfdSJing Huang  * Called by rport module to when rports are deleted.
9897725ccfdSJing Huang  */
9907725ccfdSJing Huang void
991a36c61f9SKrishna Gudipati bfa_fcs_lport_del_rport(
992a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
9937725ccfdSJing Huang 	struct bfa_fcs_rport_s *rport)
9947725ccfdSJing Huang {
995d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport));
9967725ccfdSJing Huang 	list_del(&rport->qe);
9977725ccfdSJing Huang 	port->num_rports--;
9987725ccfdSJing Huang 
9997725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
10007725ccfdSJing Huang }
10017725ccfdSJing Huang 
10025fbe25c7SJing Huang /*
10037725ccfdSJing Huang  * Called by fabric for base port when fabric login is complete.
10047725ccfdSJing Huang  * Called by vport for virtual ports when FDISC is complete.
10057725ccfdSJing Huang  */
10067725ccfdSJing Huang void
1007a36c61f9SKrishna Gudipati bfa_fcs_lport_online(struct bfa_fcs_lport_s *port)
10087725ccfdSJing Huang {
10097725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
10107725ccfdSJing Huang }
10117725ccfdSJing Huang 
10125fbe25c7SJing Huang /*
10137725ccfdSJing Huang  * Called by fabric for base port when fabric goes offline.
10147725ccfdSJing Huang  * Called by vport for virtual ports when virtual port becomes offline.
10157725ccfdSJing Huang  */
10167725ccfdSJing Huang void
1017a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port)
10187725ccfdSJing Huang {
10197725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
10207725ccfdSJing Huang }
10217725ccfdSJing Huang 
10225fbe25c7SJing Huang /*
1023881c1b3cSKrishna Gudipati  * Called by fabric for base port and by vport for virtual ports
1024881c1b3cSKrishna Gudipati  * when target mode driver is unloaded.
1025881c1b3cSKrishna Gudipati  */
1026881c1b3cSKrishna Gudipati void
1027881c1b3cSKrishna Gudipati bfa_fcs_lport_stop(struct bfa_fcs_lport_s *port)
1028881c1b3cSKrishna Gudipati {
1029881c1b3cSKrishna Gudipati 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_STOP);
1030881c1b3cSKrishna Gudipati }
1031881c1b3cSKrishna Gudipati 
1032881c1b3cSKrishna Gudipati /*
10337725ccfdSJing Huang  * Called by fabric to delete base lport and associated resources.
10347725ccfdSJing Huang  *
10357725ccfdSJing Huang  * Called by vport to delete lport and associated resources. Should call
10367725ccfdSJing Huang  * bfa_fcs_vport_delete_comp() for vports on completion.
10377725ccfdSJing Huang  */
10387725ccfdSJing Huang void
1039a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port)
10407725ccfdSJing Huang {
10417725ccfdSJing Huang 	bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
10427725ccfdSJing Huang }
10437725ccfdSJing Huang 
10445fbe25c7SJing Huang /*
10457725ccfdSJing Huang  * Return TRUE if port is online, else return FALSE
10467725ccfdSJing Huang  */
10477725ccfdSJing Huang bfa_boolean_t
1048a36c61f9SKrishna Gudipati bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port)
10497725ccfdSJing Huang {
1050a36c61f9SKrishna Gudipati 	return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online);
10517725ccfdSJing Huang }
10527725ccfdSJing Huang 
10535fbe25c7SJing Huang /*
1054e6714324SKrishna Gudipati   * Attach time initialization of logical ports.
10557725ccfdSJing Huang  */
10567725ccfdSJing Huang void
1057a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs,
1058a36c61f9SKrishna Gudipati 		   u16 vf_id, struct bfa_fcs_vport_s *vport)
10597725ccfdSJing Huang {
10607725ccfdSJing Huang 	lport->fcs = fcs;
10617725ccfdSJing Huang 	lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
10627725ccfdSJing Huang 	lport->vport = vport;
10633fd45980SKrishna Gudipati 	lport->lp_tag = (vport) ? vport->lps->bfa_tag :
10643fd45980SKrishna Gudipati 				  lport->fabric->lps->bfa_tag;
10657725ccfdSJing Huang 
10667725ccfdSJing Huang 	INIT_LIST_HEAD(&lport->rport_q);
10677725ccfdSJing Huang 	lport->num_rports = 0;
1068e6714324SKrishna Gudipati }
10697725ccfdSJing Huang 
10705fbe25c7SJing Huang /*
1071e6714324SKrishna Gudipati  * Logical port initialization of base or virtual port.
1072e6714324SKrishna Gudipati  * Called by fabric for base port or by vport for virtual ports.
1073e6714324SKrishna Gudipati  */
1074e6714324SKrishna Gudipati 
1075e6714324SKrishna Gudipati void
1076a36c61f9SKrishna Gudipati bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
1077a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg)
1078e6714324SKrishna Gudipati {
1079e6714324SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = lport->vport;
1080a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad;
1081a36c61f9SKrishna Gudipati 	char    lpwwn_buf[BFA_STRING_32];
1082e6714324SKrishna Gudipati 
10836a18b167SJing Huang 	lport->port_cfg = *port_cfg;
1084e6714324SKrishna Gudipati 
1085a36c61f9SKrishna Gudipati 	lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport,
1086e6714324SKrishna Gudipati 					lport->port_cfg.roles,
10877725ccfdSJing Huang 					lport->fabric->vf_drv,
10887725ccfdSJing Huang 					vport ? vport->vport_drv : NULL);
1089e6714324SKrishna Gudipati 
1090a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport));
109188166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
1092a36c61f9SKrishna Gudipati 		"New logical port created: WWN = %s Role = %s\n",
1093a36c61f9SKrishna Gudipati 		lpwwn_buf, "Initiator");
10947826f304SKrishna Gudipati 	bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW);
10957725ccfdSJing Huang 
1096a36c61f9SKrishna Gudipati 	bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit);
10977725ccfdSJing Huang 	bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
10987725ccfdSJing Huang }
10997725ccfdSJing Huang 
110022a08538SVijaya Mohan Guvva void
110122a08538SVijaya Mohan Guvva bfa_fcs_lport_set_symname(struct bfa_fcs_lport_s *port,
110222a08538SVijaya Mohan Guvva 				char *symname)
110322a08538SVijaya Mohan Guvva {
110422a08538SVijaya Mohan Guvva 	strcpy(port->port_cfg.sym_name.symname, symname);
110522a08538SVijaya Mohan Guvva 
110622a08538SVijaya Mohan Guvva 	if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
110722a08538SVijaya Mohan Guvva 		bfa_fcs_lport_ns_util_send_rspn_id(
110822a08538SVijaya Mohan Guvva 			BFA_FCS_GET_NS_FROM_PORT(port), NULL);
110922a08538SVijaya Mohan Guvva }
111022a08538SVijaya Mohan Guvva 
11115fbe25c7SJing Huang /*
11127725ccfdSJing Huang  *  fcs_lport_api
11137725ccfdSJing Huang  */
11147725ccfdSJing Huang 
11157725ccfdSJing Huang void
1116a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr(
1117a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port,
1118a36c61f9SKrishna Gudipati 	struct bfa_lport_attr_s *port_attr)
11197725ccfdSJing Huang {
1120a36c61f9SKrishna Gudipati 	if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
11217725ccfdSJing Huang 		port_attr->pid = port->pid;
11227725ccfdSJing Huang 	else
11237725ccfdSJing Huang 		port_attr->pid = 0;
11247725ccfdSJing Huang 
11257725ccfdSJing Huang 	port_attr->port_cfg = port->port_cfg;
11267725ccfdSJing Huang 
11277725ccfdSJing Huang 	if (port->fabric) {
1128f7f73812SMaggie Zhang 		port_attr->port_type = port->fabric->oper_type;
1129da99dcc9SMaggie Zhang 		port_attr->loopback = bfa_sm_cmp_state(port->fabric,
1130da99dcc9SMaggie Zhang 				bfa_fcs_fabric_sm_loopback);
1131f926a05fSKrishna Gudipati 		port_attr->authfail =
1132f7f73812SMaggie Zhang 			bfa_sm_cmp_state(port->fabric,
1133f7f73812SMaggie Zhang 				bfa_fcs_fabric_sm_auth_failed);
1134a36c61f9SKrishna Gudipati 		port_attr->fabric_name  = bfa_fcs_lport_get_fabric_name(port);
11357725ccfdSJing Huang 		memcpy(port_attr->fabric_ip_addr,
1136a36c61f9SKrishna Gudipati 			bfa_fcs_lport_get_fabric_ipaddr(port),
11377725ccfdSJing Huang 			BFA_FCS_FABRIC_IPADDR_SZ);
11387725ccfdSJing Huang 
113986e32dabSKrishna Gudipati 		if (port->vport != NULL) {
1140a36c61f9SKrishna Gudipati 			port_attr->port_type = BFA_PORT_TYPE_VPORT;
114186e32dabSKrishna Gudipati 			port_attr->fpma_mac =
1142f7f73812SMaggie Zhang 				port->vport->lps->lp_mac;
1143a36c61f9SKrishna Gudipati 		} else {
114486e32dabSKrishna Gudipati 			port_attr->fpma_mac =
1145f7f73812SMaggie Zhang 				port->fabric->lps->lp_mac;
1146a36c61f9SKrishna Gudipati 		}
1147a36c61f9SKrishna Gudipati 	} else {
1148a36c61f9SKrishna Gudipati 		port_attr->port_type = BFA_PORT_TYPE_UNKNOWN;
1149a36c61f9SKrishna Gudipati 		port_attr->state = BFA_LPORT_UNINIT;
1150a36c61f9SKrishna Gudipati 	}
1151a36c61f9SKrishna Gudipati }
1152a36c61f9SKrishna Gudipati 
11535fbe25c7SJing Huang /*
1154a36c61f9SKrishna Gudipati  *  bfa_fcs_lport_fab port fab functions
1155a36c61f9SKrishna Gudipati  */
1156a36c61f9SKrishna Gudipati 
11575fbe25c7SJing Huang /*
1158a36c61f9SKrishna Gudipati  *   Called by port to initialize fabric services of the base port.
1159a36c61f9SKrishna Gudipati  */
1160a36c61f9SKrishna Gudipati static void
1161a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port)
1162a36c61f9SKrishna Gudipati {
1163a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ns_init(port);
1164a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_init(port);
1165a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ms_init(port);
1166a36c61f9SKrishna Gudipati }
1167a36c61f9SKrishna Gudipati 
11685fbe25c7SJing Huang /*
1169a36c61f9SKrishna Gudipati  *   Called by port to notify transition to online state.
1170a36c61f9SKrishna Gudipati  */
1171a36c61f9SKrishna Gudipati static void
1172a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
1173a36c61f9SKrishna Gudipati {
1174a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ns_online(port);
1175bc0e2c2aSKrishna Gudipati 	bfa_fcs_lport_fab_scn_online(port);
1176a36c61f9SKrishna Gudipati }
1177a36c61f9SKrishna Gudipati 
11785fbe25c7SJing Huang /*
1179a36c61f9SKrishna Gudipati  *   Called by port to notify transition to offline state.
1180a36c61f9SKrishna Gudipati  */
1181a36c61f9SKrishna Gudipati static void
1182a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port)
1183a36c61f9SKrishna Gudipati {
1184a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ns_offline(port);
1185a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_offline(port);
1186a36c61f9SKrishna Gudipati 	bfa_fcs_lport_ms_offline(port);
1187a36c61f9SKrishna Gudipati }
1188a36c61f9SKrishna Gudipati 
11895fbe25c7SJing Huang /*
1190a36c61f9SKrishna Gudipati  *  bfa_fcs_lport_n2n  functions
1191a36c61f9SKrishna Gudipati  */
1192a36c61f9SKrishna Gudipati 
11935fbe25c7SJing Huang /*
1194a36c61f9SKrishna Gudipati  *   Called by fcs/port to initialize N2N topology.
1195a36c61f9SKrishna Gudipati  */
1196a36c61f9SKrishna Gudipati static void
1197a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port)
1198a36c61f9SKrishna Gudipati {
1199a36c61f9SKrishna Gudipati }
1200a36c61f9SKrishna Gudipati 
12015fbe25c7SJing Huang /*
1202a36c61f9SKrishna Gudipati  *   Called by fcs/port to notify transition to online state.
1203a36c61f9SKrishna Gudipati  */
1204a36c61f9SKrishna Gudipati static void
1205a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
1206a36c61f9SKrishna Gudipati {
1207a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1208a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *pcfg = &port->port_cfg;
1209a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
1210a36c61f9SKrishna Gudipati 
1211a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, pcfg->pwwn);
1212a36c61f9SKrishna Gudipati 
1213a36c61f9SKrishna Gudipati 	/*
1214a36c61f9SKrishna Gudipati 	 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
1215a36c61f9SKrishna Gudipati 	 * and assign an Address. if not, we need to wait for its PLOGI.
1216a36c61f9SKrishna Gudipati 	 *
1217a36c61f9SKrishna Gudipati 	 * If our PWWN is < than that of the remote port, it will send a PLOGI
1218a36c61f9SKrishna Gudipati 	 * with the PIDs assigned. The rport state machine take care of this
1219a36c61f9SKrishna Gudipati 	 * incoming PLOGI.
1220a36c61f9SKrishna Gudipati 	 */
1221a36c61f9SKrishna Gudipati 	if (memcmp
1222a36c61f9SKrishna Gudipati 	    ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
1223a36c61f9SKrishna Gudipati 	     sizeof(wwn_t)) > 0) {
1224a36c61f9SKrishna Gudipati 		port->pid = N2N_LOCAL_PID;
1225b704495cSKrishna Gudipati 		bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID);
12265fbe25c7SJing Huang 		/*
1227a36c61f9SKrishna Gudipati 		 * First, check if we know the device by pwwn.
1228a36c61f9SKrishna Gudipati 		 */
1229a36c61f9SKrishna Gudipati 		rport = bfa_fcs_lport_get_rport_by_pwwn(port,
1230a36c61f9SKrishna Gudipati 							n2n_port->rem_port_wwn);
1231a36c61f9SKrishna Gudipati 		if (rport) {
1232a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rport->pid);
1233a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rport->pwwn);
1234a36c61f9SKrishna Gudipati 			rport->pid = N2N_REMOTE_PID;
1235f7f73812SMaggie Zhang 			bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
1236a36c61f9SKrishna Gudipati 			return;
1237a36c61f9SKrishna Gudipati 		}
1238a36c61f9SKrishna Gudipati 
1239a36c61f9SKrishna Gudipati 		/*
1240a36c61f9SKrishna Gudipati 		 * In n2n there can be only one rport. Delete the old one
1241a36c61f9SKrishna Gudipati 		 * whose pid should be zero, because it is offline.
1242a36c61f9SKrishna Gudipati 		 */
1243a36c61f9SKrishna Gudipati 		if (port->num_rports > 0) {
1244a36c61f9SKrishna Gudipati 			rport = bfa_fcs_lport_get_rport_by_pid(port, 0);
1245d4b671c5SJing Huang 			WARN_ON(rport == NULL);
1246a36c61f9SKrishna Gudipati 			if (rport) {
1247a36c61f9SKrishna Gudipati 				bfa_trc(port->fcs, rport->pwwn);
1248f7f73812SMaggie Zhang 				bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1249a36c61f9SKrishna Gudipati 			}
1250a36c61f9SKrishna Gudipati 		}
1251a36c61f9SKrishna Gudipati 		bfa_fcs_rport_create(port, N2N_REMOTE_PID);
1252a36c61f9SKrishna Gudipati 	}
1253a36c61f9SKrishna Gudipati }
1254a36c61f9SKrishna Gudipati 
12555fbe25c7SJing Huang /*
1256a36c61f9SKrishna Gudipati  *   Called by fcs/port to notify transition to offline state.
1257a36c61f9SKrishna Gudipati  */
1258a36c61f9SKrishna Gudipati static void
1259a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
1260a36c61f9SKrishna Gudipati {
1261a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1262a36c61f9SKrishna Gudipati 
1263a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
1264a36c61f9SKrishna Gudipati 	port->pid = 0;
1265a36c61f9SKrishna Gudipati 	n2n_port->rem_port_wwn = 0;
1266a36c61f9SKrishna Gudipati 	n2n_port->reply_oxid = 0;
1267a36c61f9SKrishna Gudipati }
1268a36c61f9SKrishna Gudipati 
1269bc0e2c2aSKrishna Gudipati void
1270bc0e2c2aSKrishna Gudipati bfa_fcport_get_loop_attr(struct bfa_fcs_lport_s *port)
1271bc0e2c2aSKrishna Gudipati {
1272bc0e2c2aSKrishna Gudipati 	int i = 0, j = 0, bit = 0, alpa_bit = 0;
1273bc0e2c2aSKrishna Gudipati 	u8 k = 0;
1274bc0e2c2aSKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(port->fcs->bfa);
1275bc0e2c2aSKrishna Gudipati 
1276bc0e2c2aSKrishna Gudipati 	port->port_topo.ploop.alpabm_valid = fcport->alpabm_valid;
1277bc0e2c2aSKrishna Gudipati 	port->pid = fcport->myalpa;
1278bc0e2c2aSKrishna Gudipati 	port->pid = bfa_hton3b(port->pid);
1279bc0e2c2aSKrishna Gudipati 
1280bc0e2c2aSKrishna Gudipati 	for (i = 0; i < (FC_ALPA_MAX / 8); i++) {
1281bc0e2c2aSKrishna Gudipati 		for (j = 0, alpa_bit = 0; j < 8; j++, alpa_bit++) {
1282bc0e2c2aSKrishna Gudipati 			bfa_trc(port->fcs->bfa, fcport->alpabm.alpa_bm[i]);
1283bc0e2c2aSKrishna Gudipati 			bit = (fcport->alpabm.alpa_bm[i] & (1 << (7 - j)));
1284bc0e2c2aSKrishna Gudipati 			if (bit) {
1285bc0e2c2aSKrishna Gudipati 				port->port_topo.ploop.alpa_pos_map[k] =
1286bc0e2c2aSKrishna Gudipati 					loop_alpa_map[(i * 8) + alpa_bit];
1287bc0e2c2aSKrishna Gudipati 				k++;
1288bc0e2c2aSKrishna Gudipati 				bfa_trc(port->fcs->bfa, k);
1289bc0e2c2aSKrishna Gudipati 				bfa_trc(port->fcs->bfa,
1290bc0e2c2aSKrishna Gudipati 					 port->port_topo.ploop.alpa_pos_map[k]);
1291bc0e2c2aSKrishna Gudipati 			}
1292bc0e2c2aSKrishna Gudipati 		}
1293bc0e2c2aSKrishna Gudipati 	}
1294bc0e2c2aSKrishna Gudipati 	port->port_topo.ploop.num_alpa = k;
1295bc0e2c2aSKrishna Gudipati }
1296bc0e2c2aSKrishna Gudipati 
1297bc0e2c2aSKrishna Gudipati /*
1298bc0e2c2aSKrishna Gudipati  * Called by fcs/port to initialize Loop topology.
1299bc0e2c2aSKrishna Gudipati  */
1300bc0e2c2aSKrishna Gudipati static void
1301bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port)
1302bc0e2c2aSKrishna Gudipati {
1303bc0e2c2aSKrishna Gudipati }
1304bc0e2c2aSKrishna Gudipati 
1305bc0e2c2aSKrishna Gudipati /*
1306bc0e2c2aSKrishna Gudipati  * Called by fcs/port to notify transition to online state.
1307bc0e2c2aSKrishna Gudipati  */
1308bc0e2c2aSKrishna Gudipati static void
1309bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port)
1310bc0e2c2aSKrishna Gudipati {
1311bc0e2c2aSKrishna Gudipati 	u8 num_alpa = 0, alpabm_valid = 0;
1312bc0e2c2aSKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
1313bc0e2c2aSKrishna Gudipati 	u8 *alpa_map = NULL;
1314bc0e2c2aSKrishna Gudipati 	int i = 0;
1315bc0e2c2aSKrishna Gudipati 	u32 pid;
1316bc0e2c2aSKrishna Gudipati 
1317bc0e2c2aSKrishna Gudipati 	bfa_fcport_get_loop_attr(port);
1318bc0e2c2aSKrishna Gudipati 
1319bc0e2c2aSKrishna Gudipati 	num_alpa = port->port_topo.ploop.num_alpa;
1320bc0e2c2aSKrishna Gudipati 	alpabm_valid = port->port_topo.ploop.alpabm_valid;
1321bc0e2c2aSKrishna Gudipati 	alpa_map = port->port_topo.ploop.alpa_pos_map;
1322bc0e2c2aSKrishna Gudipati 
1323bc0e2c2aSKrishna Gudipati 	bfa_trc(port->fcs->bfa, port->pid);
1324bc0e2c2aSKrishna Gudipati 	bfa_trc(port->fcs->bfa, num_alpa);
1325bc0e2c2aSKrishna Gudipati 	if (alpabm_valid == 1) {
1326bc0e2c2aSKrishna Gudipati 		for (i = 0; i < num_alpa; i++) {
1327bc0e2c2aSKrishna Gudipati 			bfa_trc(port->fcs->bfa, alpa_map[i]);
1328bc0e2c2aSKrishna Gudipati 			if (alpa_map[i] != bfa_hton3b(port->pid)) {
1329bc0e2c2aSKrishna Gudipati 				pid = alpa_map[i];
1330bc0e2c2aSKrishna Gudipati 				bfa_trc(port->fcs->bfa, pid);
1331bc0e2c2aSKrishna Gudipati 				rport = bfa_fcs_lport_get_rport_by_pid(port,
1332bc0e2c2aSKrishna Gudipati 						bfa_hton3b(pid));
1333bc0e2c2aSKrishna Gudipati 				if (!rport)
1334bc0e2c2aSKrishna Gudipati 					rport = bfa_fcs_rport_create(port,
1335bc0e2c2aSKrishna Gudipati 						bfa_hton3b(pid));
1336bc0e2c2aSKrishna Gudipati 			}
1337bc0e2c2aSKrishna Gudipati 		}
1338bc0e2c2aSKrishna Gudipati 	} else {
1339bc0e2c2aSKrishna Gudipati 		for (i = 0; i < MAX_ALPA_COUNT; i++) {
1340bc0e2c2aSKrishna Gudipati 			if (alpa_map[i] != port->pid) {
1341bc0e2c2aSKrishna Gudipati 				pid = loop_alpa_map[i];
1342bc0e2c2aSKrishna Gudipati 				bfa_trc(port->fcs->bfa, pid);
1343bc0e2c2aSKrishna Gudipati 				rport = bfa_fcs_lport_get_rport_by_pid(port,
1344bc0e2c2aSKrishna Gudipati 						bfa_hton3b(pid));
1345bc0e2c2aSKrishna Gudipati 				if (!rport)
1346bc0e2c2aSKrishna Gudipati 					rport = bfa_fcs_rport_create(port,
1347bc0e2c2aSKrishna Gudipati 						bfa_hton3b(pid));
1348bc0e2c2aSKrishna Gudipati 			}
1349bc0e2c2aSKrishna Gudipati 		}
1350bc0e2c2aSKrishna Gudipati 	}
1351bc0e2c2aSKrishna Gudipati }
1352bc0e2c2aSKrishna Gudipati 
1353bc0e2c2aSKrishna Gudipati /*
1354bc0e2c2aSKrishna Gudipati  * Called by fcs/port to notify transition to offline state.
1355bc0e2c2aSKrishna Gudipati  */
1356bc0e2c2aSKrishna Gudipati static void
1357bc0e2c2aSKrishna Gudipati bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port)
1358bc0e2c2aSKrishna Gudipati {
1359bc0e2c2aSKrishna Gudipati }
1360bc0e2c2aSKrishna Gudipati 
1361a36c61f9SKrishna Gudipati #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
1362a36c61f9SKrishna Gudipati 
1363a36c61f9SKrishna Gudipati /*
1364a36c61f9SKrishna Gudipati  * forward declarations
1365a36c61f9SKrishna Gudipati  */
1366a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg,
1367a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
1368a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg,
1369a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
1370a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg,
1371a36c61f9SKrishna Gudipati 					   struct bfa_fcxp_s *fcxp_alloced);
1372a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_rhba_response(void *fcsarg,
1373a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
1374a36c61f9SKrishna Gudipati 						void *cbarg,
1375a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
1376a36c61f9SKrishna Gudipati 						u32 rsp_len,
1377a36c61f9SKrishna Gudipati 						u32 resid_len,
1378a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
1379a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_rprt_response(void *fcsarg,
1380a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
1381a36c61f9SKrishna Gudipati 						void *cbarg,
1382a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
1383a36c61f9SKrishna Gudipati 						u32 rsp_len,
1384a36c61f9SKrishna Gudipati 						u32 resid_len,
1385a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
1386a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_rpa_response(void *fcsarg,
1387a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
1388a36c61f9SKrishna Gudipati 					       void *cbarg,
1389a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
1390a36c61f9SKrishna Gudipati 					       u32 rsp_len,
1391a36c61f9SKrishna Gudipati 					       u32 resid_len,
1392a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
1393a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_timeout(void *arg);
1394a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1395a36c61f9SKrishna Gudipati 						  u8 *pyld);
1396a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1397a36c61f9SKrishna Gudipati 						  u8 *pyld);
1398a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1399a36c61f9SKrishna Gudipati 						 u8 *pyld);
1400a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *
1401a36c61f9SKrishna Gudipati 						       fdmi, u8 *pyld);
1402a36c61f9SKrishna Gudipati static void	bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1403a36c61f9SKrishna Gudipati 				 struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
1404a36c61f9SKrishna Gudipati static void	bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1405a36c61f9SKrishna Gudipati 				  struct bfa_fcs_fdmi_port_attr_s *port_attr);
1406d7be54ccSKrishna Gudipati u32	bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed);
1407d7be54ccSKrishna Gudipati 
14085fbe25c7SJing Huang /*
1409a36c61f9SKrishna Gudipati  *  fcs_fdmi_sm FCS FDMI state machine
1410a36c61f9SKrishna Gudipati  */
1411a36c61f9SKrishna Gudipati 
14125fbe25c7SJing Huang /*
1413a36c61f9SKrishna Gudipati  *  FDMI State Machine events
1414a36c61f9SKrishna Gudipati  */
1415a36c61f9SKrishna Gudipati enum port_fdmi_event {
1416a36c61f9SKrishna Gudipati 	FDMISM_EVENT_PORT_ONLINE = 1,
1417a36c61f9SKrishna Gudipati 	FDMISM_EVENT_PORT_OFFLINE = 2,
1418a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RSP_OK = 4,
1419a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RSP_ERROR = 5,
1420a36c61f9SKrishna Gudipati 	FDMISM_EVENT_TIMEOUT = 6,
1421a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RHBA_SENT = 7,
1422a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RPRT_SENT = 8,
1423a36c61f9SKrishna Gudipati 	FDMISM_EVENT_RPA_SENT = 9,
1424a36c61f9SKrishna Gudipati };
1425a36c61f9SKrishna Gudipati 
1426a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1427a36c61f9SKrishna Gudipati 					     enum port_fdmi_event event);
1428a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_sending_rhba(
1429a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1430a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1431a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1432a36c61f9SKrishna Gudipati 					  enum port_fdmi_event event);
1433a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rhba_retry(
1434a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1435a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1436a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_sending_rprt(
1437a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1438a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1439a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1440a36c61f9SKrishna Gudipati 					  enum port_fdmi_event event);
1441a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rprt_retry(
1442a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1443a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1444a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_sending_rpa(
1445a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1446a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1447a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1448a36c61f9SKrishna Gudipati 					 enum port_fdmi_event event);
1449a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_rpa_retry(
1450a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1451a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
1452a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1453a36c61f9SKrishna Gudipati 					    enum port_fdmi_event event);
1454a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_fdmi_sm_disabled(
1455a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_fdmi_s *fdmi,
1456a36c61f9SKrishna Gudipati 				enum port_fdmi_event event);
14575fbe25c7SJing Huang /*
1458a36c61f9SKrishna Gudipati  *	Start in offline state - awaiting MS to send start.
1459a36c61f9SKrishna Gudipati  */
1460a36c61f9SKrishna Gudipati static void
1461a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1462a36c61f9SKrishna Gudipati 			     enum port_fdmi_event event)
1463a36c61f9SKrishna Gudipati {
1464a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1465a36c61f9SKrishna Gudipati 
1466a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1467a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1468a36c61f9SKrishna Gudipati 
1469a36c61f9SKrishna Gudipati 	fdmi->retry_cnt = 0;
1470a36c61f9SKrishna Gudipati 
1471a36c61f9SKrishna Gudipati 	switch (event) {
1472a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_ONLINE:
1473a36c61f9SKrishna Gudipati 		if (port->vport) {
1474a36c61f9SKrishna Gudipati 			/*
1475a36c61f9SKrishna Gudipati 			 * For Vports, register a new port.
1476a36c61f9SKrishna Gudipati 			 */
1477a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1478a36c61f9SKrishna Gudipati 					 bfa_fcs_lport_fdmi_sm_sending_rprt);
1479a36c61f9SKrishna Gudipati 			bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1480a36c61f9SKrishna Gudipati 		} else {
1481a36c61f9SKrishna Gudipati 			/*
1482a36c61f9SKrishna Gudipati 			 * For a base port, we should first register the HBA
148325985edcSLucas De Marchi 			 * attribute. The HBA attribute also contains the base
1484a36c61f9SKrishna Gudipati 			 *  port registration.
1485a36c61f9SKrishna Gudipati 			 */
1486a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1487a36c61f9SKrishna Gudipati 					 bfa_fcs_lport_fdmi_sm_sending_rhba);
1488a36c61f9SKrishna Gudipati 			bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1489a36c61f9SKrishna Gudipati 		}
1490a36c61f9SKrishna Gudipati 		break;
1491a36c61f9SKrishna Gudipati 
1492a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1493a36c61f9SKrishna Gudipati 		break;
1494a36c61f9SKrishna Gudipati 
1495a36c61f9SKrishna Gudipati 	default:
1496a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1497a36c61f9SKrishna Gudipati 	}
1498a36c61f9SKrishna Gudipati }
1499a36c61f9SKrishna Gudipati 
1500a36c61f9SKrishna Gudipati static void
1501a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1502a36c61f9SKrishna Gudipati 				  enum port_fdmi_event event)
1503a36c61f9SKrishna Gudipati {
1504a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1505a36c61f9SKrishna Gudipati 
1506a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1507a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1508a36c61f9SKrishna Gudipati 
1509a36c61f9SKrishna Gudipati 	switch (event) {
1510a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RHBA_SENT:
1511a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba);
1512a36c61f9SKrishna Gudipati 		break;
1513a36c61f9SKrishna Gudipati 
1514a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1515a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1516a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1517a36c61f9SKrishna Gudipati 					   &fdmi->fcxp_wqe);
1518a36c61f9SKrishna Gudipati 		break;
1519a36c61f9SKrishna Gudipati 
1520a36c61f9SKrishna Gudipati 	default:
1521a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1522a36c61f9SKrishna Gudipati 	}
1523a36c61f9SKrishna Gudipati }
1524a36c61f9SKrishna Gudipati 
1525a36c61f9SKrishna Gudipati static void
1526a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1527a36c61f9SKrishna Gudipati 			enum port_fdmi_event event)
1528a36c61f9SKrishna Gudipati {
1529a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1530a36c61f9SKrishna Gudipati 
1531a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1532a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1533a36c61f9SKrishna Gudipati 
1534a36c61f9SKrishna Gudipati 	switch (event) {
1535a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_ERROR:
1536a36c61f9SKrishna Gudipati 		/*
1537a36c61f9SKrishna Gudipati 		 * if max retries have not been reached, start timer for a
1538a36c61f9SKrishna Gudipati 		 * delayed retry
1539a36c61f9SKrishna Gudipati 		 */
1540a36c61f9SKrishna Gudipati 		if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1541a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1542a36c61f9SKrishna Gudipati 					bfa_fcs_lport_fdmi_sm_rhba_retry);
1543a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1544a36c61f9SKrishna Gudipati 					    &fdmi->timer,
1545a36c61f9SKrishna Gudipati 					    bfa_fcs_lport_fdmi_timeout, fdmi,
1546a36c61f9SKrishna Gudipati 					    BFA_FCS_RETRY_TIMEOUT);
1547a36c61f9SKrishna Gudipati 		} else {
1548a36c61f9SKrishna Gudipati 			/*
1549a36c61f9SKrishna Gudipati 			 * set state to offline
1550a36c61f9SKrishna Gudipati 			 */
1551a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1552a36c61f9SKrishna Gudipati 		}
1553a36c61f9SKrishna Gudipati 		break;
1554a36c61f9SKrishna Gudipati 
1555a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_OK:
1556a36c61f9SKrishna Gudipati 		/*
1557a36c61f9SKrishna Gudipati 		 * Initiate Register Port Attributes
1558a36c61f9SKrishna Gudipati 		 */
1559a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1560a36c61f9SKrishna Gudipati 		fdmi->retry_cnt = 0;
1561a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1562a36c61f9SKrishna Gudipati 		break;
1563a36c61f9SKrishna Gudipati 
1564a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1565a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(fdmi->fcxp);
1566a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1567a36c61f9SKrishna Gudipati 		break;
1568a36c61f9SKrishna Gudipati 
1569a36c61f9SKrishna Gudipati 	default:
1570a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1571a36c61f9SKrishna Gudipati 	}
1572a36c61f9SKrishna Gudipati }
1573a36c61f9SKrishna Gudipati 
1574a36c61f9SKrishna Gudipati static void
1575a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1576a36c61f9SKrishna Gudipati 				enum port_fdmi_event event)
1577a36c61f9SKrishna Gudipati {
1578a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1579a36c61f9SKrishna Gudipati 
1580a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1581a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1582a36c61f9SKrishna Gudipati 
1583a36c61f9SKrishna Gudipati 	switch (event) {
1584a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_TIMEOUT:
1585a36c61f9SKrishna Gudipati 		/*
1586a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
1587a36c61f9SKrishna Gudipati 		 */
1588a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba);
1589a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1590a36c61f9SKrishna Gudipati 		break;
1591a36c61f9SKrishna Gudipati 
1592a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1593a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1594a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fdmi->timer);
1595a36c61f9SKrishna Gudipati 		break;
1596a36c61f9SKrishna Gudipati 
1597a36c61f9SKrishna Gudipati 	default:
1598a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1599a36c61f9SKrishna Gudipati 	}
1600a36c61f9SKrishna Gudipati }
1601a36c61f9SKrishna Gudipati 
1602a36c61f9SKrishna Gudipati /*
1603a36c61f9SKrishna Gudipati * RPRT : Register Port
1604a36c61f9SKrishna Gudipati  */
1605a36c61f9SKrishna Gudipati static void
1606a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1607a36c61f9SKrishna Gudipati 				  enum port_fdmi_event event)
1608a36c61f9SKrishna Gudipati {
1609a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1610a36c61f9SKrishna Gudipati 
1611a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1612a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1613a36c61f9SKrishna Gudipati 
1614a36c61f9SKrishna Gudipati 	switch (event) {
1615a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RPRT_SENT:
1616a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt);
1617a36c61f9SKrishna Gudipati 		break;
1618a36c61f9SKrishna Gudipati 
1619a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1620a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1621a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1622a36c61f9SKrishna Gudipati 					   &fdmi->fcxp_wqe);
1623a36c61f9SKrishna Gudipati 		break;
1624a36c61f9SKrishna Gudipati 
1625a36c61f9SKrishna Gudipati 	default:
1626a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1627a36c61f9SKrishna Gudipati 	}
1628a36c61f9SKrishna Gudipati }
1629a36c61f9SKrishna Gudipati 
1630a36c61f9SKrishna Gudipati static void
1631a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1632a36c61f9SKrishna Gudipati 			enum port_fdmi_event event)
1633a36c61f9SKrishna Gudipati {
1634a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1635a36c61f9SKrishna Gudipati 
1636a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1637a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1638a36c61f9SKrishna Gudipati 
1639a36c61f9SKrishna Gudipati 	switch (event) {
1640a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_ERROR:
1641a36c61f9SKrishna Gudipati 		/*
1642a36c61f9SKrishna Gudipati 		 * if max retries have not been reached, start timer for a
1643a36c61f9SKrishna Gudipati 		 * delayed retry
1644a36c61f9SKrishna Gudipati 		 */
1645a36c61f9SKrishna Gudipati 		if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1646a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi,
1647a36c61f9SKrishna Gudipati 					bfa_fcs_lport_fdmi_sm_rprt_retry);
1648a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1649a36c61f9SKrishna Gudipati 					    &fdmi->timer,
1650a36c61f9SKrishna Gudipati 					    bfa_fcs_lport_fdmi_timeout, fdmi,
1651a36c61f9SKrishna Gudipati 					    BFA_FCS_RETRY_TIMEOUT);
16527725ccfdSJing Huang 
16537725ccfdSJing Huang 		} else {
1654a36c61f9SKrishna Gudipati 			/*
1655a36c61f9SKrishna Gudipati 			 * set state to offline
1656a36c61f9SKrishna Gudipati 			 */
1657a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1658a36c61f9SKrishna Gudipati 			fdmi->retry_cnt = 0;
16597725ccfdSJing Huang 		}
1660a36c61f9SKrishna Gudipati 		break;
1661a36c61f9SKrishna Gudipati 
1662a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_OK:
1663a36c61f9SKrishna Gudipati 		fdmi->retry_cnt = 0;
1664a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1665a36c61f9SKrishna Gudipati 		break;
1666a36c61f9SKrishna Gudipati 
1667a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1668a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(fdmi->fcxp);
1669a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1670a36c61f9SKrishna Gudipati 		break;
1671a36c61f9SKrishna Gudipati 
1672a36c61f9SKrishna Gudipati 	default:
1673a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1674a36c61f9SKrishna Gudipati 	}
1675a36c61f9SKrishna Gudipati }
1676a36c61f9SKrishna Gudipati 
1677a36c61f9SKrishna Gudipati static void
1678a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1679a36c61f9SKrishna Gudipati 				enum port_fdmi_event event)
1680a36c61f9SKrishna Gudipati {
1681a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1682a36c61f9SKrishna Gudipati 
1683a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1684a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1685a36c61f9SKrishna Gudipati 
1686a36c61f9SKrishna Gudipati 	switch (event) {
1687a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_TIMEOUT:
1688a36c61f9SKrishna Gudipati 		/*
1689a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
1690a36c61f9SKrishna Gudipati 		 */
1691a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt);
1692a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1693a36c61f9SKrishna Gudipati 		break;
1694a36c61f9SKrishna Gudipati 
1695a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1696a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1697a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fdmi->timer);
1698a36c61f9SKrishna Gudipati 		break;
1699a36c61f9SKrishna Gudipati 
1700a36c61f9SKrishna Gudipati 	default:
1701a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1702a36c61f9SKrishna Gudipati 	}
1703a36c61f9SKrishna Gudipati }
1704a36c61f9SKrishna Gudipati 
1705a36c61f9SKrishna Gudipati /*
1706a36c61f9SKrishna Gudipati  * Register Port Attributes
1707a36c61f9SKrishna Gudipati  */
1708a36c61f9SKrishna Gudipati static void
1709a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1710a36c61f9SKrishna Gudipati 				 enum port_fdmi_event event)
1711a36c61f9SKrishna Gudipati {
1712a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1713a36c61f9SKrishna Gudipati 
1714a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1715a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1716a36c61f9SKrishna Gudipati 
1717a36c61f9SKrishna Gudipati 	switch (event) {
1718a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RPA_SENT:
1719a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa);
1720a36c61f9SKrishna Gudipati 		break;
1721a36c61f9SKrishna Gudipati 
1722a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1723a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1724a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1725a36c61f9SKrishna Gudipati 					   &fdmi->fcxp_wqe);
1726a36c61f9SKrishna Gudipati 		break;
1727a36c61f9SKrishna Gudipati 
1728a36c61f9SKrishna Gudipati 	default:
1729a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1730a36c61f9SKrishna Gudipati 	}
1731a36c61f9SKrishna Gudipati }
1732a36c61f9SKrishna Gudipati 
1733a36c61f9SKrishna Gudipati static void
1734a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1735a36c61f9SKrishna Gudipati 			enum port_fdmi_event event)
1736a36c61f9SKrishna Gudipati {
1737a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1738a36c61f9SKrishna Gudipati 
1739a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1740a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1741a36c61f9SKrishna Gudipati 
1742a36c61f9SKrishna Gudipati 	switch (event) {
1743a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_ERROR:
1744a36c61f9SKrishna Gudipati 		/*
1745a36c61f9SKrishna Gudipati 		 * if max retries have not been reached, start timer for a
1746a36c61f9SKrishna Gudipati 		 * delayed retry
1747a36c61f9SKrishna Gudipati 		 */
1748a36c61f9SKrishna Gudipati 		if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1749a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry);
1750a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1751a36c61f9SKrishna Gudipati 					    &fdmi->timer,
1752a36c61f9SKrishna Gudipati 					    bfa_fcs_lport_fdmi_timeout, fdmi,
1753a36c61f9SKrishna Gudipati 					    BFA_FCS_RETRY_TIMEOUT);
1754a36c61f9SKrishna Gudipati 		} else {
1755a36c61f9SKrishna Gudipati 			/*
1756a36c61f9SKrishna Gudipati 			 * set state to offline
1757a36c61f9SKrishna Gudipati 			 */
1758a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1759a36c61f9SKrishna Gudipati 			fdmi->retry_cnt = 0;
1760a36c61f9SKrishna Gudipati 		}
1761a36c61f9SKrishna Gudipati 		break;
1762a36c61f9SKrishna Gudipati 
1763a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_RSP_OK:
1764a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1765a36c61f9SKrishna Gudipati 		fdmi->retry_cnt = 0;
1766a36c61f9SKrishna Gudipati 		break;
1767a36c61f9SKrishna Gudipati 
1768a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1769a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(fdmi->fcxp);
1770a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1771a36c61f9SKrishna Gudipati 		break;
1772a36c61f9SKrishna Gudipati 
1773a36c61f9SKrishna Gudipati 	default:
1774a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1775a36c61f9SKrishna Gudipati 	}
1776a36c61f9SKrishna Gudipati }
1777a36c61f9SKrishna Gudipati 
1778a36c61f9SKrishna Gudipati static void
1779a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1780a36c61f9SKrishna Gudipati 			       enum port_fdmi_event event)
1781a36c61f9SKrishna Gudipati {
1782a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1783a36c61f9SKrishna Gudipati 
1784a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1785a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1786a36c61f9SKrishna Gudipati 
1787a36c61f9SKrishna Gudipati 	switch (event) {
1788a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_TIMEOUT:
1789a36c61f9SKrishna Gudipati 		/*
1790a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
1791a36c61f9SKrishna Gudipati 		 */
1792a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1793a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1794a36c61f9SKrishna Gudipati 		break;
1795a36c61f9SKrishna Gudipati 
1796a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1797a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1798a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fdmi->timer);
1799a36c61f9SKrishna Gudipati 		break;
1800a36c61f9SKrishna Gudipati 
1801a36c61f9SKrishna Gudipati 	default:
1802a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1803a36c61f9SKrishna Gudipati 	}
1804a36c61f9SKrishna Gudipati }
1805a36c61f9SKrishna Gudipati 
1806a36c61f9SKrishna Gudipati static void
1807a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1808a36c61f9SKrishna Gudipati 				enum port_fdmi_event event)
1809a36c61f9SKrishna Gudipati {
1810a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1811a36c61f9SKrishna Gudipati 
1812a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1813a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1814a36c61f9SKrishna Gudipati 
1815a36c61f9SKrishna Gudipati 	switch (event) {
1816a36c61f9SKrishna Gudipati 	case FDMISM_EVENT_PORT_OFFLINE:
1817a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1818a36c61f9SKrishna Gudipati 		break;
1819a36c61f9SKrishna Gudipati 
1820a36c61f9SKrishna Gudipati 	default:
1821a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
1822a36c61f9SKrishna Gudipati 	}
1823a36c61f9SKrishna Gudipati }
18245fbe25c7SJing Huang /*
1825a36c61f9SKrishna Gudipati  *  FDMI is disabled state.
1826a36c61f9SKrishna Gudipati  */
1827a36c61f9SKrishna Gudipati static void
1828a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi,
1829a36c61f9SKrishna Gudipati 			     enum port_fdmi_event event)
1830a36c61f9SKrishna Gudipati {
1831a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1832a36c61f9SKrishna Gudipati 
1833a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1834a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, event);
1835a36c61f9SKrishna Gudipati 
1836a36c61f9SKrishna Gudipati 	/* No op State. It can only be enabled at Driver Init. */
1837a36c61f9SKrishna Gudipati }
1838a36c61f9SKrishna Gudipati 
18395fbe25c7SJing Huang /*
1840a36c61f9SKrishna Gudipati *  RHBA : Register HBA Attributes.
1841a36c61f9SKrishna Gudipati  */
1842a36c61f9SKrishna Gudipati static void
1843a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1844a36c61f9SKrishna Gudipati {
1845a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1846a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1847a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
1848a36c61f9SKrishna Gudipati 	int             len, attr_len;
1849a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1850a36c61f9SKrishna Gudipati 	u8        *pyld;
1851a36c61f9SKrishna Gudipati 
1852a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
1853a36c61f9SKrishna Gudipati 
1854c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1855c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1856a36c61f9SKrishna Gudipati 	if (!fcxp) {
1857a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1858c3f1b123SKrishna Gudipati 				bfa_fcs_lport_fdmi_send_rhba, fdmi, BFA_TRUE);
1859a36c61f9SKrishna Gudipati 		return;
1860a36c61f9SKrishna Gudipati 	}
1861a36c61f9SKrishna Gudipati 	fdmi->fcxp = fcxp;
1862a36c61f9SKrishna Gudipati 
1863a36c61f9SKrishna Gudipati 	pyld = bfa_fcxp_get_reqbuf(fcxp);
18646a18b167SJing Huang 	memset(pyld, 0, FC_MAX_PDUSZ);
1865a36c61f9SKrishna Gudipati 
1866a36c61f9SKrishna Gudipati 	len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
1867a36c61f9SKrishna Gudipati 				   FDMI_RHBA);
1868a36c61f9SKrishna Gudipati 
1869a36c61f9SKrishna Gudipati 	attr_len =
1870a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi,
1871a36c61f9SKrishna Gudipati 					  (u8 *) ((struct ct_hdr_s *) pyld
1872a36c61f9SKrishna Gudipati 						       + 1));
1873a36c61f9SKrishna Gudipati 
1874a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1875a36c61f9SKrishna Gudipati 			  FC_CLASS_3, (len + attr_len), &fchs,
1876a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi,
1877a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
1878a36c61f9SKrishna Gudipati 
1879a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
1880a36c61f9SKrishna Gudipati }
1881a36c61f9SKrishna Gudipati 
1882a36c61f9SKrishna Gudipati static          u16
1883a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
1884a36c61f9SKrishna Gudipati {
1885a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
1886a36c61f9SKrishna Gudipati 	struct bfa_fcs_fdmi_hba_attr_s hba_attr;
1887a36c61f9SKrishna Gudipati 	struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr;
1888a36c61f9SKrishna Gudipati 	struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld;
1889a36c61f9SKrishna Gudipati 	struct fdmi_attr_s *attr;
1890a36c61f9SKrishna Gudipati 	u8        *curr_ptr;
1891a36c61f9SKrishna Gudipati 	u16        len, count;
189250444a34SMaggie 	u16	templen;
1893a36c61f9SKrishna Gudipati 
1894a36c61f9SKrishna Gudipati 	/*
1895a36c61f9SKrishna Gudipati 	 * get hba attributes
1896a36c61f9SKrishna Gudipati 	 */
1897a36c61f9SKrishna Gudipati 	bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
1898a36c61f9SKrishna Gudipati 
1899a36c61f9SKrishna Gudipati 	rhba->hba_id = bfa_fcs_lport_get_pwwn(port);
1900ba816ea8SJing Huang 	rhba->port_list.num_ports = cpu_to_be32(1);
1901a36c61f9SKrishna Gudipati 	rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port);
1902a36c61f9SKrishna Gudipati 
1903a36c61f9SKrishna Gudipati 	len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
1904a36c61f9SKrishna Gudipati 
1905a36c61f9SKrishna Gudipati 	count = 0;
1906a36c61f9SKrishna Gudipati 	len += sizeof(rhba->hba_attr_blk.attr_count);
1907a36c61f9SKrishna Gudipati 
1908a36c61f9SKrishna Gudipati 	/*
1909a36c61f9SKrishna Gudipati 	 * fill out the invididual entries of the HBA attrib Block
1910a36c61f9SKrishna Gudipati 	 */
1911a36c61f9SKrishna Gudipati 	curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
1912a36c61f9SKrishna Gudipati 
1913a36c61f9SKrishna Gudipati 	/*
1914a36c61f9SKrishna Gudipati 	 * Node Name
1915a36c61f9SKrishna Gudipati 	 */
1916a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1917ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME);
191850444a34SMaggie 	templen = sizeof(wwn_t);
191950444a34SMaggie 	memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen);
192050444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
192150444a34SMaggie 	len += templen;
1922a36c61f9SKrishna Gudipati 	count++;
192350444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
192450444a34SMaggie 			     sizeof(templen));
1925a36c61f9SKrishna Gudipati 
1926a36c61f9SKrishna Gudipati 	/*
1927a36c61f9SKrishna Gudipati 	 * Manufacturer
1928a36c61f9SKrishna Gudipati 	 */
1929a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1930ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER);
193150444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->manufacturer);
193250444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->manufacturer, templen);
193350444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
193450444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
193550444a34SMaggie 	len += templen;
1936a36c61f9SKrishna Gudipati 	count++;
193750444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
193850444a34SMaggie 			     sizeof(templen));
1939a36c61f9SKrishna Gudipati 
1940a36c61f9SKrishna Gudipati 	/*
1941a36c61f9SKrishna Gudipati 	 * Serial Number
1942a36c61f9SKrishna Gudipati 	 */
1943a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1944ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM);
194550444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->serial_num);
194650444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->serial_num, templen);
194750444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
194850444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
194950444a34SMaggie 	len += templen;
1950a36c61f9SKrishna Gudipati 	count++;
195150444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
195250444a34SMaggie 			     sizeof(templen));
1953a36c61f9SKrishna Gudipati 
1954a36c61f9SKrishna Gudipati 	/*
1955a36c61f9SKrishna Gudipati 	 * Model
1956a36c61f9SKrishna Gudipati 	 */
1957a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1958ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL);
195950444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->model);
196050444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->model, templen);
196150444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
196250444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
196350444a34SMaggie 	len += templen;
1964a36c61f9SKrishna Gudipati 	count++;
196550444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
196650444a34SMaggie 			     sizeof(templen));
1967a36c61f9SKrishna Gudipati 
1968a36c61f9SKrishna Gudipati 	/*
1969a36c61f9SKrishna Gudipati 	 * Model Desc
1970a36c61f9SKrishna Gudipati 	 */
1971a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
1972ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC);
197350444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->model_desc);
197450444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->model_desc, templen);
197550444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
197650444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
197750444a34SMaggie 	len += templen;
1978a36c61f9SKrishna Gudipati 	count++;
197950444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
198050444a34SMaggie 			     sizeof(templen));
1981a36c61f9SKrishna Gudipati 
1982a36c61f9SKrishna Gudipati 	/*
1983a36c61f9SKrishna Gudipati 	 * H/W Version
1984a36c61f9SKrishna Gudipati 	 */
1985a36c61f9SKrishna Gudipati 	if (fcs_hba_attr->hw_version[0] != '\0') {
1986a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
1987ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION);
198850444a34SMaggie 		templen = (u16) strlen(fcs_hba_attr->hw_version);
198950444a34SMaggie 		memcpy(attr->value, fcs_hba_attr->hw_version, templen);
199050444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
199150444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
199250444a34SMaggie 		len += templen;
1993a36c61f9SKrishna Gudipati 		count++;
199450444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
199550444a34SMaggie 					 sizeof(templen));
1996a36c61f9SKrishna Gudipati 	}
1997a36c61f9SKrishna Gudipati 
1998a36c61f9SKrishna Gudipati 	/*
1999a36c61f9SKrishna Gudipati 	 * Driver Version
2000a36c61f9SKrishna Gudipati 	 */
2001a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2002ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION);
200350444a34SMaggie 	templen = (u16) strlen(fcs_hba_attr->driver_version);
200450444a34SMaggie 	memcpy(attr->value, fcs_hba_attr->driver_version, templen);
200550444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
200650444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2007dd5aaf45SKrishna Gudipati 	len += templen;
2008a36c61f9SKrishna Gudipati 	count++;
200950444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
201050444a34SMaggie 			     sizeof(templen));
2011a36c61f9SKrishna Gudipati 
2012a36c61f9SKrishna Gudipati 	/*
2013a36c61f9SKrishna Gudipati 	 * Option Rom Version
2014a36c61f9SKrishna Gudipati 	 */
2015a36c61f9SKrishna Gudipati 	if (fcs_hba_attr->option_rom_ver[0] != '\0') {
2016a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
2017ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION);
201850444a34SMaggie 		templen = (u16) strlen(fcs_hba_attr->option_rom_ver);
201950444a34SMaggie 		memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen);
202050444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
202150444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
202250444a34SMaggie 		len += templen;
2023a36c61f9SKrishna Gudipati 		count++;
202450444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
202550444a34SMaggie 					 sizeof(templen));
2026a36c61f9SKrishna Gudipati 	}
2027a36c61f9SKrishna Gudipati 
2028a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2029ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION);
2030b480a32eSKrishna Gudipati 	templen = (u16) strlen(fcs_hba_attr->fw_version);
2031b480a32eSKrishna Gudipati 	memcpy(attr->value, fcs_hba_attr->fw_version, templen);
203250444a34SMaggie 	templen = fc_roundup(templen, sizeof(u32));
203350444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
203450444a34SMaggie 	len += templen;
2035a36c61f9SKrishna Gudipati 	count++;
203650444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
203750444a34SMaggie 			     sizeof(templen));
2038a36c61f9SKrishna Gudipati 
2039a36c61f9SKrishna Gudipati 	/*
2040a36c61f9SKrishna Gudipati 	 * OS Name
2041a36c61f9SKrishna Gudipati 	 */
2042a36c61f9SKrishna Gudipati 	if (fcs_hba_attr->os_name[0] != '\0') {
2043a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
2044ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME);
204550444a34SMaggie 		templen = (u16) strlen(fcs_hba_attr->os_name);
204650444a34SMaggie 		memcpy(attr->value, fcs_hba_attr->os_name, templen);
204750444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
204850444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
204950444a34SMaggie 		len += templen;
2050a36c61f9SKrishna Gudipati 		count++;
205150444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
205250444a34SMaggie 					sizeof(templen));
2053a36c61f9SKrishna Gudipati 	}
2054a36c61f9SKrishna Gudipati 
2055a36c61f9SKrishna Gudipati 	/*
2056a36c61f9SKrishna Gudipati 	 * MAX_CT_PAYLOAD
2057a36c61f9SKrishna Gudipati 	 */
2058a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2059ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT);
206050444a34SMaggie 	templen = sizeof(fcs_hba_attr->max_ct_pyld);
206150444a34SMaggie 	memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen);
2062d7cbc304SVijaya Mohan Guvva 	templen = fc_roundup(templen, sizeof(u32));
2063d7cbc304SVijaya Mohan Guvva 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
206450444a34SMaggie 	len += templen;
2065a36c61f9SKrishna Gudipati 	count++;
206650444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
206750444a34SMaggie 			     sizeof(templen));
2068d7cbc304SVijaya Mohan Guvva 	/*
2069d7cbc304SVijaya Mohan Guvva 	 * Send extended attributes ( FOS 7.1 support )
2070d7cbc304SVijaya Mohan Guvva 	 */
2071d7cbc304SVijaya Mohan Guvva 	if (fdmi->retry_cnt == 0) {
2072d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2073d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODE_SYM_NAME);
2074d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_hba_attr->node_sym_name);
2075d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_hba_attr->node_sym_name, templen);
2076d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2077d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2078d7cbc304SVijaya Mohan Guvva 		len += templen;
2079d7cbc304SVijaya Mohan Guvva 		count++;
2080d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2081d7cbc304SVijaya Mohan Guvva 					sizeof(templen));
2082d7cbc304SVijaya Mohan Guvva 
2083d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2084d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_VENDOR_ID);
2085d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_hba_attr->vendor_info);
2086d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_hba_attr->vendor_info, templen);
2087d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2088d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2089d7cbc304SVijaya Mohan Guvva 		len += templen;
2090d7cbc304SVijaya Mohan Guvva 		count++;
2091d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2092d7cbc304SVijaya Mohan Guvva 					sizeof(templen));
2093d7cbc304SVijaya Mohan Guvva 
2094d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2095d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NUM_PORTS);
2096d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_hba_attr->num_ports);
2097d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_hba_attr->num_ports, templen);
2098d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2099d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2100d7cbc304SVijaya Mohan Guvva 		len += templen;
2101d7cbc304SVijaya Mohan Guvva 		count++;
2102d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2103d7cbc304SVijaya Mohan Guvva 					sizeof(templen));
2104d7cbc304SVijaya Mohan Guvva 
2105d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2106d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FABRIC_NAME);
2107d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_hba_attr->fabric_name);
2108d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_hba_attr->fabric_name, templen);
2109d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2110d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2111d7cbc304SVijaya Mohan Guvva 		len += templen;
2112d7cbc304SVijaya Mohan Guvva 		count++;
2113d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2114d7cbc304SVijaya Mohan Guvva 					sizeof(templen));
2115d7cbc304SVijaya Mohan Guvva 
2116d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2117d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_BIOS_VER);
2118d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_hba_attr->bios_ver);
2119d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_hba_attr->bios_ver, templen);
2120d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(attr->len, sizeof(u32));
2121d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2122d7cbc304SVijaya Mohan Guvva 		len += templen;
2123d7cbc304SVijaya Mohan Guvva 		count++;
2124d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2125d7cbc304SVijaya Mohan Guvva 					sizeof(templen));
2126d7cbc304SVijaya Mohan Guvva 	}
2127a36c61f9SKrishna Gudipati 
2128a36c61f9SKrishna Gudipati 	/*
2129a36c61f9SKrishna Gudipati 	 * Update size of payload
2130a36c61f9SKrishna Gudipati 	 */
21315fbe25c7SJing Huang 	len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
2132a36c61f9SKrishna Gudipati 
2133ba816ea8SJing Huang 	rhba->hba_attr_blk.attr_count = cpu_to_be32(count);
2134a36c61f9SKrishna Gudipati 	return len;
2135a36c61f9SKrishna Gudipati }
2136a36c61f9SKrishna Gudipati 
2137a36c61f9SKrishna Gudipati static void
2138a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2139a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
2140a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
2141a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
2142a36c61f9SKrishna Gudipati {
2143a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi =
2144a36c61f9SKrishna Gudipati 				(struct bfa_fcs_lport_fdmi_s *) cbarg;
2145a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2146a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
2147a36c61f9SKrishna Gudipati 
2148a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2149a36c61f9SKrishna Gudipati 
2150a36c61f9SKrishna Gudipati 	/*
2151a36c61f9SKrishna Gudipati 	 * Sanity Checks
2152a36c61f9SKrishna Gudipati 	 */
2153a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2154a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
2155a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2156a36c61f9SKrishna Gudipati 		return;
2157a36c61f9SKrishna Gudipati 	}
2158a36c61f9SKrishna Gudipati 
2159a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2160ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2161a36c61f9SKrishna Gudipati 
2162a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2163a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2164a36c61f9SKrishna Gudipati 		return;
2165a36c61f9SKrishna Gudipati 	}
2166a36c61f9SKrishna Gudipati 
2167a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
2168a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
2169a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2170a36c61f9SKrishna Gudipati }
2171a36c61f9SKrishna Gudipati 
21725fbe25c7SJing Huang /*
2173a36c61f9SKrishna Gudipati *  RPRT : Register Port
2174a36c61f9SKrishna Gudipati  */
2175a36c61f9SKrishna Gudipati static void
2176a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2177a36c61f9SKrishna Gudipati {
2178a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
2179a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2180a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
2181a36c61f9SKrishna Gudipati 	u16        len, attr_len;
2182a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2183a36c61f9SKrishna Gudipati 	u8        *pyld;
2184a36c61f9SKrishna Gudipati 
2185a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2186a36c61f9SKrishna Gudipati 
2187c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
2188c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2189a36c61f9SKrishna Gudipati 	if (!fcxp) {
2190a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2191c3f1b123SKrishna Gudipati 				bfa_fcs_lport_fdmi_send_rprt, fdmi, BFA_TRUE);
2192a36c61f9SKrishna Gudipati 		return;
2193a36c61f9SKrishna Gudipati 	}
2194a36c61f9SKrishna Gudipati 	fdmi->fcxp = fcxp;
2195a36c61f9SKrishna Gudipati 
2196a36c61f9SKrishna Gudipati 	pyld = bfa_fcxp_get_reqbuf(fcxp);
21976a18b167SJing Huang 	memset(pyld, 0, FC_MAX_PDUSZ);
2198a36c61f9SKrishna Gudipati 
2199a36c61f9SKrishna Gudipati 	len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2200a36c61f9SKrishna Gudipati 				   FDMI_RPRT);
2201a36c61f9SKrishna Gudipati 
2202a36c61f9SKrishna Gudipati 	attr_len =
2203a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi,
2204a36c61f9SKrishna Gudipati 					  (u8 *) ((struct ct_hdr_s *) pyld
2205a36c61f9SKrishna Gudipati 						       + 1));
2206a36c61f9SKrishna Gudipati 
2207a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2208a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len + attr_len, &fchs,
2209a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi,
2210a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
2211a36c61f9SKrishna Gudipati 
2212a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
2213a36c61f9SKrishna Gudipati }
2214a36c61f9SKrishna Gudipati 
22155fbe25c7SJing Huang /*
2216a36c61f9SKrishna Gudipati  * This routine builds Port Attribute Block that used in RPA, RPRT commands.
2217a36c61f9SKrishna Gudipati  */
2218a36c61f9SKrishna Gudipati static          u16
2219a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
2220a36c61f9SKrishna Gudipati 				       u8 *pyld)
2221a36c61f9SKrishna Gudipati {
2222a36c61f9SKrishna Gudipati 	struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
2223a36c61f9SKrishna Gudipati 	struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld;
2224a36c61f9SKrishna Gudipati 	struct fdmi_attr_s *attr;
2225a36c61f9SKrishna Gudipati 	u8        *curr_ptr;
2226a36c61f9SKrishna Gudipati 	u16        len;
2227a36c61f9SKrishna Gudipati 	u8	count = 0;
222850444a34SMaggie 	u16	templen;
2229a36c61f9SKrishna Gudipati 
2230a36c61f9SKrishna Gudipati 	/*
2231a36c61f9SKrishna Gudipati 	 * get port attributes
2232a36c61f9SKrishna Gudipati 	 */
2233a36c61f9SKrishna Gudipati 	bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
2234a36c61f9SKrishna Gudipati 
2235a36c61f9SKrishna Gudipati 	len = sizeof(port_attrib->attr_count);
2236a36c61f9SKrishna Gudipati 
2237a36c61f9SKrishna Gudipati 	/*
2238a36c61f9SKrishna Gudipati 	 * fill out the invididual entries
2239a36c61f9SKrishna Gudipati 	 */
2240a36c61f9SKrishna Gudipati 	curr_ptr = (u8 *) &port_attrib->port_attr;
2241a36c61f9SKrishna Gudipati 
2242a36c61f9SKrishna Gudipati 	/*
2243a36c61f9SKrishna Gudipati 	 * FC4 Types
2244a36c61f9SKrishna Gudipati 	 */
2245a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2246ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES);
224750444a34SMaggie 	templen = sizeof(fcs_port_attr.supp_fc4_types);
224850444a34SMaggie 	memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen);
224950444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
225050444a34SMaggie 	len += templen;
2251a36c61f9SKrishna Gudipati 	++count;
2252a36c61f9SKrishna Gudipati 	attr->len =
225350444a34SMaggie 		cpu_to_be16(templen + sizeof(attr->type) +
225450444a34SMaggie 			     sizeof(templen));
2255a36c61f9SKrishna Gudipati 
2256a36c61f9SKrishna Gudipati 	/*
2257a36c61f9SKrishna Gudipati 	 * Supported Speed
2258a36c61f9SKrishna Gudipati 	 */
2259a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2260ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED);
226150444a34SMaggie 	templen = sizeof(fcs_port_attr.supp_speed);
226250444a34SMaggie 	memcpy(attr->value, &fcs_port_attr.supp_speed, templen);
226350444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
226450444a34SMaggie 	len += templen;
2265a36c61f9SKrishna Gudipati 	++count;
2266a36c61f9SKrishna Gudipati 	attr->len =
226750444a34SMaggie 		cpu_to_be16(templen + sizeof(attr->type) +
226850444a34SMaggie 			     sizeof(templen));
2269a36c61f9SKrishna Gudipati 
2270a36c61f9SKrishna Gudipati 	/*
2271a36c61f9SKrishna Gudipati 	 * current Port Speed
2272a36c61f9SKrishna Gudipati 	 */
2273a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2274ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED);
227550444a34SMaggie 	templen = sizeof(fcs_port_attr.curr_speed);
227650444a34SMaggie 	memcpy(attr->value, &fcs_port_attr.curr_speed, templen);
227750444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
227850444a34SMaggie 	len += templen;
2279a36c61f9SKrishna Gudipati 	++count;
228050444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
228150444a34SMaggie 			     sizeof(templen));
2282a36c61f9SKrishna Gudipati 
2283a36c61f9SKrishna Gudipati 	/*
2284a36c61f9SKrishna Gudipati 	 * max frame size
2285a36c61f9SKrishna Gudipati 	 */
2286a36c61f9SKrishna Gudipati 	attr = (struct fdmi_attr_s *) curr_ptr;
2287ba816ea8SJing Huang 	attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE);
228850444a34SMaggie 	templen = sizeof(fcs_port_attr.max_frm_size);
228950444a34SMaggie 	memcpy(attr->value, &fcs_port_attr.max_frm_size, templen);
229050444a34SMaggie 	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
229150444a34SMaggie 	len += templen;
2292a36c61f9SKrishna Gudipati 	++count;
229350444a34SMaggie 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
229450444a34SMaggie 			     sizeof(templen));
2295a36c61f9SKrishna Gudipati 
2296a36c61f9SKrishna Gudipati 	/*
2297a36c61f9SKrishna Gudipati 	 * OS Device Name
2298a36c61f9SKrishna Gudipati 	 */
2299a36c61f9SKrishna Gudipati 	if (fcs_port_attr.os_device_name[0] != '\0') {
2300a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
2301ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME);
230250444a34SMaggie 		templen = (u16) strlen(fcs_port_attr.os_device_name);
230350444a34SMaggie 		memcpy(attr->value, fcs_port_attr.os_device_name, templen);
230450444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
230550444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
230650444a34SMaggie 		len += templen;
2307a36c61f9SKrishna Gudipati 		++count;
230850444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
230950444a34SMaggie 					sizeof(templen));
2310a36c61f9SKrishna Gudipati 	}
2311a36c61f9SKrishna Gudipati 	/*
2312a36c61f9SKrishna Gudipati 	 * Host Name
2313a36c61f9SKrishna Gudipati 	 */
2314a36c61f9SKrishna Gudipati 	if (fcs_port_attr.host_name[0] != '\0') {
2315a36c61f9SKrishna Gudipati 		attr = (struct fdmi_attr_s *) curr_ptr;
2316ba816ea8SJing Huang 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME);
231750444a34SMaggie 		templen = (u16) strlen(fcs_port_attr.host_name);
231850444a34SMaggie 		memcpy(attr->value, fcs_port_attr.host_name, templen);
231950444a34SMaggie 		templen = fc_roundup(templen, sizeof(u32));
232050444a34SMaggie 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
232150444a34SMaggie 		len += templen;
2322a36c61f9SKrishna Gudipati 		++count;
232350444a34SMaggie 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
232450444a34SMaggie 				sizeof(templen));
2325a36c61f9SKrishna Gudipati 	}
2326a36c61f9SKrishna Gudipati 
2327d7cbc304SVijaya Mohan Guvva 	if (fdmi->retry_cnt == 0) {
2328d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2329d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_NODE_NAME);
2330d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_port_attr.node_name);
2331d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_port_attr.node_name, templen);
2332d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2333d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2334d7cbc304SVijaya Mohan Guvva 		len += templen;
2335d7cbc304SVijaya Mohan Guvva 		++count;
2336d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2337d7cbc304SVijaya Mohan Guvva 				 sizeof(templen));
2338d7cbc304SVijaya Mohan Guvva 
2339d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2340d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NAME);
2341d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_port_attr.port_name);
2342d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_port_attr.port_name, templen);
2343d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2344d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(attr->len) + templen;
2345d7cbc304SVijaya Mohan Guvva 		len += templen;
2346d7cbc304SVijaya Mohan Guvva 		++count;
2347d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2348d7cbc304SVijaya Mohan Guvva 				 sizeof(templen));
2349d7cbc304SVijaya Mohan Guvva 
2350d7cbc304SVijaya Mohan Guvva 		if (fcs_port_attr.port_sym_name.symname[0] != '\0') {
2351d7cbc304SVijaya Mohan Guvva 			attr = (struct fdmi_attr_s *) curr_ptr;
2352d7cbc304SVijaya Mohan Guvva 			attr->type =
2353d7cbc304SVijaya Mohan Guvva 				cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SYM_NAME);
2354d7cbc304SVijaya Mohan Guvva 			templen = sizeof(fcs_port_attr.port_sym_name);
2355d7cbc304SVijaya Mohan Guvva 			memcpy(attr->value,
2356d7cbc304SVijaya Mohan Guvva 				&fcs_port_attr.port_sym_name, templen);
2357d7cbc304SVijaya Mohan Guvva 			templen = fc_roundup(templen, sizeof(u32));
2358d7cbc304SVijaya Mohan Guvva 			curr_ptr += sizeof(attr->type) +
2359d7cbc304SVijaya Mohan Guvva 					sizeof(templen) + templen;
2360d7cbc304SVijaya Mohan Guvva 			len += templen;
2361d7cbc304SVijaya Mohan Guvva 			++count;
2362d7cbc304SVijaya Mohan Guvva 			attr->len = cpu_to_be16(templen +
2363d7cbc304SVijaya Mohan Guvva 				sizeof(attr->type) + sizeof(templen));
2364d7cbc304SVijaya Mohan Guvva 		}
2365d7cbc304SVijaya Mohan Guvva 
2366d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2367d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_TYPE);
2368d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_port_attr.port_type);
2369d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_port_attr.port_type, templen);
2370d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2371d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2372d7cbc304SVijaya Mohan Guvva 		len += templen;
2373d7cbc304SVijaya Mohan Guvva 		++count;
2374d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2375d7cbc304SVijaya Mohan Guvva 				 sizeof(templen));
2376d7cbc304SVijaya Mohan Guvva 
2377d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2378d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_COS);
2379d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_port_attr.scos);
2380d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_port_attr.scos, templen);
2381d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2382d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2383d7cbc304SVijaya Mohan Guvva 		len += templen;
2384d7cbc304SVijaya Mohan Guvva 		++count;
2385d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2386d7cbc304SVijaya Mohan Guvva 				 sizeof(templen));
2387d7cbc304SVijaya Mohan Guvva 
2388d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2389d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FAB_NAME);
2390d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_port_attr.port_fabric_name);
2391d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_port_attr.port_fabric_name, templen);
2392d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2393d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2394d7cbc304SVijaya Mohan Guvva 		len += templen;
2395d7cbc304SVijaya Mohan Guvva 		++count;
2396d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2397d7cbc304SVijaya Mohan Guvva 				 sizeof(templen));
2398d7cbc304SVijaya Mohan Guvva 
2399d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2400d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FC4_TYPE);
2401d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_port_attr.port_act_fc4_type);
2402d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, fcs_port_attr.port_act_fc4_type,
2403d7cbc304SVijaya Mohan Guvva 				templen);
2404d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2405d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2406d7cbc304SVijaya Mohan Guvva 		len += templen;
2407d7cbc304SVijaya Mohan Guvva 		++count;
2408d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2409d7cbc304SVijaya Mohan Guvva 				 sizeof(templen));
2410d7cbc304SVijaya Mohan Guvva 
2411d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2412d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_STATE);
2413d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_port_attr.port_state);
2414d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_port_attr.port_state, templen);
2415d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2416d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2417d7cbc304SVijaya Mohan Guvva 		len += templen;
2418d7cbc304SVijaya Mohan Guvva 		++count;
2419d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2420d7cbc304SVijaya Mohan Guvva 				 sizeof(templen));
2421d7cbc304SVijaya Mohan Guvva 
2422d7cbc304SVijaya Mohan Guvva 		attr = (struct fdmi_attr_s *) curr_ptr;
2423d7cbc304SVijaya Mohan Guvva 		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NUM_RPRT);
2424d7cbc304SVijaya Mohan Guvva 		templen = sizeof(fcs_port_attr.num_ports);
2425d7cbc304SVijaya Mohan Guvva 		memcpy(attr->value, &fcs_port_attr.num_ports, templen);
2426d7cbc304SVijaya Mohan Guvva 		templen = fc_roundup(templen, sizeof(u32));
2427d7cbc304SVijaya Mohan Guvva 		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2428d7cbc304SVijaya Mohan Guvva 		len += templen;
2429d7cbc304SVijaya Mohan Guvva 		++count;
2430d7cbc304SVijaya Mohan Guvva 		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2431d7cbc304SVijaya Mohan Guvva 				sizeof(templen));
2432d7cbc304SVijaya Mohan Guvva 	}
2433d7cbc304SVijaya Mohan Guvva 
2434a36c61f9SKrishna Gudipati 	/*
2435a36c61f9SKrishna Gudipati 	 * Update size of payload
2436a36c61f9SKrishna Gudipati 	 */
2437ba816ea8SJing Huang 	port_attrib->attr_count = cpu_to_be32(count);
24385fbe25c7SJing Huang 	len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
2439a36c61f9SKrishna Gudipati 	return len;
2440a36c61f9SKrishna Gudipati }
2441a36c61f9SKrishna Gudipati 
2442a36c61f9SKrishna Gudipati static          u16
2443a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2444a36c61f9SKrishna Gudipati {
2445a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2446a36c61f9SKrishna Gudipati 	struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld;
2447a36c61f9SKrishna Gudipati 	u16        len;
2448a36c61f9SKrishna Gudipati 
2449a36c61f9SKrishna Gudipati 	rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs));
2450a36c61f9SKrishna Gudipati 	rprt->port_name = bfa_fcs_lport_get_pwwn(port);
2451a36c61f9SKrishna Gudipati 
2452a36c61f9SKrishna Gudipati 	len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2453a36c61f9SKrishna Gudipati 				(u8 *) &rprt->port_attr_blk);
2454a36c61f9SKrishna Gudipati 
2455a36c61f9SKrishna Gudipati 	len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
2456a36c61f9SKrishna Gudipati 
2457a36c61f9SKrishna Gudipati 	return len;
2458a36c61f9SKrishna Gudipati }
2459a36c61f9SKrishna Gudipati 
2460a36c61f9SKrishna Gudipati static void
2461a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2462a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
2463a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
2464a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
2465a36c61f9SKrishna Gudipati {
2466a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi =
2467a36c61f9SKrishna Gudipati 			(struct bfa_fcs_lport_fdmi_s *) cbarg;
2468a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2469a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
2470a36c61f9SKrishna Gudipati 
2471a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2472a36c61f9SKrishna Gudipati 
2473a36c61f9SKrishna Gudipati 	/*
2474a36c61f9SKrishna Gudipati 	 * Sanity Checks
2475a36c61f9SKrishna Gudipati 	 */
2476a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2477a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
2478a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2479a36c61f9SKrishna Gudipati 		return;
2480a36c61f9SKrishna Gudipati 	}
2481a36c61f9SKrishna Gudipati 
2482a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2483ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2484a36c61f9SKrishna Gudipati 
2485a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2486a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2487a36c61f9SKrishna Gudipati 		return;
2488a36c61f9SKrishna Gudipati 	}
2489a36c61f9SKrishna Gudipati 
2490a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
2491a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
2492a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2493a36c61f9SKrishna Gudipati }
2494a36c61f9SKrishna Gudipati 
24955fbe25c7SJing Huang /*
2496a36c61f9SKrishna Gudipati *  RPA : Register Port Attributes.
2497a36c61f9SKrishna Gudipati  */
2498a36c61f9SKrishna Gudipati static void
2499a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2500a36c61f9SKrishna Gudipati {
2501a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
2502a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2503a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
2504a36c61f9SKrishna Gudipati 	u16        len, attr_len;
2505a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2506a36c61f9SKrishna Gudipati 	u8        *pyld;
2507a36c61f9SKrishna Gudipati 
2508a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2509a36c61f9SKrishna Gudipati 
2510c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
2511c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2512a36c61f9SKrishna Gudipati 	if (!fcxp) {
2513a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2514c3f1b123SKrishna Gudipati 				bfa_fcs_lport_fdmi_send_rpa, fdmi, BFA_TRUE);
2515a36c61f9SKrishna Gudipati 		return;
2516a36c61f9SKrishna Gudipati 	}
2517a36c61f9SKrishna Gudipati 	fdmi->fcxp = fcxp;
2518a36c61f9SKrishna Gudipati 
2519a36c61f9SKrishna Gudipati 	pyld = bfa_fcxp_get_reqbuf(fcxp);
25206a18b167SJing Huang 	memset(pyld, 0, FC_MAX_PDUSZ);
2521a36c61f9SKrishna Gudipati 
2522a36c61f9SKrishna Gudipati 	len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2523a36c61f9SKrishna Gudipati 				   FDMI_RPA);
2524a36c61f9SKrishna Gudipati 
25255fbe25c7SJing Huang 	attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi,
25265fbe25c7SJing Huang 				(u8 *) ((struct ct_hdr_s *) pyld + 1));
2527a36c61f9SKrishna Gudipati 
2528a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2529a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len + attr_len, &fchs,
2530a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi,
2531a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
2532a36c61f9SKrishna Gudipati 
2533a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
2534a36c61f9SKrishna Gudipati }
2535a36c61f9SKrishna Gudipati 
2536a36c61f9SKrishna Gudipati static          u16
2537a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2538a36c61f9SKrishna Gudipati {
2539a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2540a36c61f9SKrishna Gudipati 	struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld;
2541a36c61f9SKrishna Gudipati 	u16        len;
2542a36c61f9SKrishna Gudipati 
2543a36c61f9SKrishna Gudipati 	rpa->port_name = bfa_fcs_lport_get_pwwn(port);
2544a36c61f9SKrishna Gudipati 
2545a36c61f9SKrishna Gudipati 	len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2546a36c61f9SKrishna Gudipati 				(u8 *) &rpa->port_attr_blk);
2547a36c61f9SKrishna Gudipati 
2548a36c61f9SKrishna Gudipati 	len += sizeof(rpa->port_name);
2549a36c61f9SKrishna Gudipati 
2550a36c61f9SKrishna Gudipati 	return len;
2551a36c61f9SKrishna Gudipati }
2552a36c61f9SKrishna Gudipati 
2553a36c61f9SKrishna Gudipati static void
2554a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2555a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
2556a36c61f9SKrishna Gudipati 			u32 resid_len, struct fchs_s *rsp_fchs)
2557a36c61f9SKrishna Gudipati {
2558a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi =
2559a36c61f9SKrishna Gudipati 				(struct bfa_fcs_lport_fdmi_s *) cbarg;
2560a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2561a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
2562a36c61f9SKrishna Gudipati 
2563a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
2564a36c61f9SKrishna Gudipati 
2565a36c61f9SKrishna Gudipati 	/*
2566a36c61f9SKrishna Gudipati 	 * Sanity Checks
2567a36c61f9SKrishna Gudipati 	 */
2568a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2569a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
2570a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2571a36c61f9SKrishna Gudipati 		return;
2572a36c61f9SKrishna Gudipati 	}
2573a36c61f9SKrishna Gudipati 
2574a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2575ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2576a36c61f9SKrishna Gudipati 
2577a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2578a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2579a36c61f9SKrishna Gudipati 		return;
2580a36c61f9SKrishna Gudipati 	}
2581a36c61f9SKrishna Gudipati 
2582a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
2583a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
2584a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2585a36c61f9SKrishna Gudipati }
2586a36c61f9SKrishna Gudipati 
2587a36c61f9SKrishna Gudipati static void
2588a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout(void *arg)
2589a36c61f9SKrishna Gudipati {
2590a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg;
2591a36c61f9SKrishna Gudipati 
2592a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
2593a36c61f9SKrishna Gudipati }
2594a36c61f9SKrishna Gudipati 
259552f94b6fSMaggie static void
2596a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2597a36c61f9SKrishna Gudipati 			 struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
2598a36c61f9SKrishna Gudipati {
2599a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2600a36c61f9SKrishna Gudipati 	struct bfa_fcs_driver_info_s  *driver_info = &port->fcs->driver_info;
2601b480a32eSKrishna Gudipati 	struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
2602a36c61f9SKrishna Gudipati 
26036a18b167SJing Huang 	memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
2604a36c61f9SKrishna Gudipati 
2605a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
2606a36c61f9SKrishna Gudipati 					hba_attr->manufacturer);
2607a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
2608a36c61f9SKrishna Gudipati 					hba_attr->serial_num);
2609a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2610a36c61f9SKrishna Gudipati 					hba_attr->model);
2611a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2612a36c61f9SKrishna Gudipati 					hba_attr->model_desc);
2613a36c61f9SKrishna Gudipati 	bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc,
2614a36c61f9SKrishna Gudipati 					hba_attr->hw_version);
2615a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
2616a36c61f9SKrishna Gudipati 					hba_attr->option_rom_ver);
2617a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc,
2618a36c61f9SKrishna Gudipati 					hba_attr->fw_version);
2619a36c61f9SKrishna Gudipati 
2620a36c61f9SKrishna Gudipati 	strncpy(hba_attr->driver_version, (char *)driver_info->version,
2621a36c61f9SKrishna Gudipati 		sizeof(hba_attr->driver_version));
2622a36c61f9SKrishna Gudipati 
2623a36c61f9SKrishna Gudipati 	strncpy(hba_attr->os_name, driver_info->host_os_name,
2624a36c61f9SKrishna Gudipati 		sizeof(hba_attr->os_name));
2625a36c61f9SKrishna Gudipati 
2626a36c61f9SKrishna Gudipati 	/*
2627a36c61f9SKrishna Gudipati 	 * If there is a patch level, append it
2628a36c61f9SKrishna Gudipati 	 * to the os name along with a separator
2629a36c61f9SKrishna Gudipati 	 */
2630a36c61f9SKrishna Gudipati 	if (driver_info->host_os_patch[0] != '\0') {
2631a36c61f9SKrishna Gudipati 		strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
2632a36c61f9SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
2633a36c61f9SKrishna Gudipati 		strncat(hba_attr->os_name, driver_info->host_os_patch,
2634a36c61f9SKrishna Gudipati 				sizeof(driver_info->host_os_patch));
2635a36c61f9SKrishna Gudipati 	}
2636a36c61f9SKrishna Gudipati 
2637b480a32eSKrishna Gudipati 	/* Retrieve the max frame size from the port attr */
2638b480a32eSKrishna Gudipati 	bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
2639b480a32eSKrishna Gudipati 	hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size;
2640d7cbc304SVijaya Mohan Guvva 
2641d7cbc304SVijaya Mohan Guvva 	strncpy(hba_attr->node_sym_name.symname,
2642d7cbc304SVijaya Mohan Guvva 		port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN);
2643d7cbc304SVijaya Mohan Guvva 	strcpy(hba_attr->vendor_info, "BROCADE");
2644d7cbc304SVijaya Mohan Guvva 	hba_attr->num_ports =
2645d7cbc304SVijaya Mohan Guvva 		cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc));
2646d7cbc304SVijaya Mohan Guvva 	hba_attr->fabric_name = port->fabric->lps->pr_nwwn;
2647d7cbc304SVijaya Mohan Guvva 	strncpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN);
2648d7cbc304SVijaya Mohan Guvva 
2649a36c61f9SKrishna Gudipati }
2650a36c61f9SKrishna Gudipati 
265152f94b6fSMaggie static void
2652a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2653a36c61f9SKrishna Gudipati 			  struct bfa_fcs_fdmi_port_attr_s *port_attr)
2654a36c61f9SKrishna Gudipati {
2655a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
2656a36c61f9SKrishna Gudipati 	struct bfa_fcs_driver_info_s  *driver_info = &port->fcs->driver_info;
2657a36c61f9SKrishna Gudipati 	struct bfa_port_attr_s pport_attr;
2658d7cbc304SVijaya Mohan Guvva 	struct bfa_lport_attr_s lport_attr;
2659a36c61f9SKrishna Gudipati 
26606a18b167SJing Huang 	memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
2661a36c61f9SKrishna Gudipati 
2662a36c61f9SKrishna Gudipati 	/*
2663a36c61f9SKrishna Gudipati 	 * get pport attributes from hal
2664a36c61f9SKrishna Gudipati 	 */
2665a36c61f9SKrishna Gudipati 	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2666a36c61f9SKrishna Gudipati 
2667a36c61f9SKrishna Gudipati 	/*
2668a36c61f9SKrishna Gudipati 	 * get FC4 type Bitmask
2669a36c61f9SKrishna Gudipati 	 */
2670a36c61f9SKrishna Gudipati 	fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
2671a36c61f9SKrishna Gudipati 
2672a36c61f9SKrishna Gudipati 	/*
2673a36c61f9SKrishna Gudipati 	 * Supported Speeds
2674a36c61f9SKrishna Gudipati 	 */
2675d7be54ccSKrishna Gudipati 	switch (pport_attr.speed_supported) {
2676d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_16GBPS:
2677d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2678d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G);
2679d7be54ccSKrishna Gudipati 		break;
2680d7be54ccSKrishna Gudipati 
2681d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_10GBPS:
2682d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2683d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G);
2684d7be54ccSKrishna Gudipati 		break;
2685d7be54ccSKrishna Gudipati 
2686d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_8GBPS:
2687d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2688d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G);
2689d7be54ccSKrishna Gudipati 		break;
2690d7be54ccSKrishna Gudipati 
2691d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_4GBPS:
2692d7be54ccSKrishna Gudipati 		port_attr->supp_speed =
2693d7be54ccSKrishna Gudipati 			cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G);
2694d7be54ccSKrishna Gudipati 		break;
2695d7be54ccSKrishna Gudipati 
2696d7be54ccSKrishna Gudipati 	default:
2697d7be54ccSKrishna Gudipati 		bfa_sm_fault(port->fcs, pport_attr.speed_supported);
2698d7be54ccSKrishna Gudipati 	}
2699a36c61f9SKrishna Gudipati 
2700a36c61f9SKrishna Gudipati 	/*
2701a36c61f9SKrishna Gudipati 	 * Current Speed
2702a36c61f9SKrishna Gudipati 	 */
2703d7be54ccSKrishna Gudipati 	port_attr->curr_speed = cpu_to_be32(
2704d7be54ccSKrishna Gudipati 				bfa_fcs_fdmi_convert_speed(pport_attr.speed));
2705a36c61f9SKrishna Gudipati 
2706a36c61f9SKrishna Gudipati 	/*
2707a36c61f9SKrishna Gudipati 	 * Max PDU Size.
2708a36c61f9SKrishna Gudipati 	 */
2709b480a32eSKrishna Gudipati 	port_attr->max_frm_size = cpu_to_be32(pport_attr.pport_cfg.maxfrsize);
2710a36c61f9SKrishna Gudipati 
2711a36c61f9SKrishna Gudipati 	/*
2712a36c61f9SKrishna Gudipati 	 * OS device Name
2713a36c61f9SKrishna Gudipati 	 */
2714a36c61f9SKrishna Gudipati 	strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
2715a36c61f9SKrishna Gudipati 		sizeof(port_attr->os_device_name));
2716a36c61f9SKrishna Gudipati 
2717a36c61f9SKrishna Gudipati 	/*
2718a36c61f9SKrishna Gudipati 	 * Host name
2719a36c61f9SKrishna Gudipati 	 */
2720a36c61f9SKrishna Gudipati 	strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
2721a36c61f9SKrishna Gudipati 		sizeof(port_attr->host_name));
27227725ccfdSJing Huang 
2723d7cbc304SVijaya Mohan Guvva 	port_attr->node_name = bfa_fcs_lport_get_nwwn(port);
2724d7cbc304SVijaya Mohan Guvva 	port_attr->port_name = bfa_fcs_lport_get_pwwn(port);
2725d7cbc304SVijaya Mohan Guvva 
2726d7cbc304SVijaya Mohan Guvva 	strncpy(port_attr->port_sym_name.symname,
2727d7cbc304SVijaya Mohan Guvva 		(char *)&bfa_fcs_lport_get_psym_name(port), BFA_SYMNAME_MAXLEN);
2728d7cbc304SVijaya Mohan Guvva 	bfa_fcs_lport_get_attr(port, &lport_attr);
2729d7cbc304SVijaya Mohan Guvva 	port_attr->port_type = cpu_to_be32(lport_attr.port_type);
2730d7cbc304SVijaya Mohan Guvva 	port_attr->scos = pport_attr.cos_supported;
2731d7cbc304SVijaya Mohan Guvva 	port_attr->port_fabric_name = port->fabric->lps->pr_nwwn;
2732d7cbc304SVijaya Mohan Guvva 	fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->port_act_fc4_type);
2733d7cbc304SVijaya Mohan Guvva 	port_attr->port_state = cpu_to_be32(pport_attr.port_state);
2734d7cbc304SVijaya Mohan Guvva 	port_attr->num_ports = cpu_to_be32(port->num_rports);
27357725ccfdSJing Huang }
27367725ccfdSJing Huang 
2737d7be54ccSKrishna Gudipati /*
2738d7be54ccSKrishna Gudipati  * Convert BFA speed to FDMI format.
2739d7be54ccSKrishna Gudipati  */
2740d7be54ccSKrishna Gudipati u32
2741d7be54ccSKrishna Gudipati bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed)
2742d7be54ccSKrishna Gudipati {
2743d7be54ccSKrishna Gudipati 	u32	ret;
2744d7be54ccSKrishna Gudipati 
2745d7be54ccSKrishna Gudipati 	switch (pport_speed) {
2746d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_1GBPS:
2747d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_2GBPS:
2748d7be54ccSKrishna Gudipati 		ret = pport_speed;
2749d7be54ccSKrishna Gudipati 		break;
2750d7be54ccSKrishna Gudipati 
2751d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_4GBPS:
2752d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_4G;
2753d7be54ccSKrishna Gudipati 		break;
2754d7be54ccSKrishna Gudipati 
2755d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_8GBPS:
2756d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_8G;
2757d7be54ccSKrishna Gudipati 		break;
2758d7be54ccSKrishna Gudipati 
2759d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_10GBPS:
2760d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_10G;
2761d7be54ccSKrishna Gudipati 		break;
2762d7be54ccSKrishna Gudipati 
2763d7be54ccSKrishna Gudipati 	case BFA_PORT_SPEED_16GBPS:
2764d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_16G;
2765d7be54ccSKrishna Gudipati 		break;
2766d7be54ccSKrishna Gudipati 
2767d7be54ccSKrishna Gudipati 	default:
2768d7be54ccSKrishna Gudipati 		ret = FDMI_TRANS_SPEED_UNKNOWN;
2769d7be54ccSKrishna Gudipati 	}
2770d7be54ccSKrishna Gudipati 	return ret;
2771d7be54ccSKrishna Gudipati }
27727725ccfdSJing Huang 
2773a36c61f9SKrishna Gudipati void
2774a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms)
2775a36c61f9SKrishna Gudipati {
2776a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2777a36c61f9SKrishna Gudipati 
2778a36c61f9SKrishna Gudipati 	fdmi->ms = ms;
2779a36c61f9SKrishna Gudipati 	if (ms->port->fcs->fdmi_enabled)
2780a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
2781a36c61f9SKrishna Gudipati 	else
2782a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled);
2783a36c61f9SKrishna Gudipati }
2784a36c61f9SKrishna Gudipati 
2785a36c61f9SKrishna Gudipati void
2786a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms)
2787a36c61f9SKrishna Gudipati {
2788a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2789a36c61f9SKrishna Gudipati 
2790a36c61f9SKrishna Gudipati 	fdmi->ms = ms;
2791a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
2792a36c61f9SKrishna Gudipati }
2793a36c61f9SKrishna Gudipati 
2794a36c61f9SKrishna Gudipati void
2795a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms)
2796a36c61f9SKrishna Gudipati {
2797a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2798a36c61f9SKrishna Gudipati 
2799a36c61f9SKrishna Gudipati 	fdmi->ms = ms;
2800a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
2801a36c61f9SKrishna Gudipati }
2802a36c61f9SKrishna Gudipati 
2803a36c61f9SKrishna Gudipati #define BFA_FCS_MS_CMD_MAX_RETRIES  2
2804a36c61f9SKrishna Gudipati 
2805a36c61f9SKrishna Gudipati /*
2806a36c61f9SKrishna Gudipati  * forward declarations
2807a36c61f9SKrishna Gudipati  */
2808a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_send_plogi(void *ms_cbarg,
2809a36c61f9SKrishna Gudipati 					   struct bfa_fcxp_s *fcxp_alloced);
2810a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_timeout(void *arg);
2811a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_plogi_response(void *fcsarg,
2812a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
2813a36c61f9SKrishna Gudipati 					       void *cbarg,
2814a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
2815a36c61f9SKrishna Gudipati 					       u32 rsp_len,
2816a36c61f9SKrishna Gudipati 					       u32 resid_len,
2817a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
2818a36c61f9SKrishna Gudipati 
2819a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_ms_send_gmal(void *ms_cbarg,
2820a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
2821a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_gmal_response(void *fcsarg,
2822a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
2823a36c61f9SKrishna Gudipati 					       void *cbarg,
2824a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
2825a36c61f9SKrishna Gudipati 					       u32 rsp_len,
2826a36c61f9SKrishna Gudipati 					       u32 resid_len,
2827a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
2828a36c61f9SKrishna Gudipati static void	bfa_fcs_lport_ms_send_gfn(void *ms_cbarg,
2829a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
2830a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_gfn_response(void *fcsarg,
2831a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
2832a36c61f9SKrishna Gudipati 					       void *cbarg,
2833a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
2834a36c61f9SKrishna Gudipati 					       u32 rsp_len,
2835a36c61f9SKrishna Gudipati 					       u32 resid_len,
2836a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
28375fbe25c7SJing Huang /*
2838a36c61f9SKrishna Gudipati  *  fcs_ms_sm FCS MS state machine
2839a36c61f9SKrishna Gudipati  */
2840a36c61f9SKrishna Gudipati 
28415fbe25c7SJing Huang /*
2842a36c61f9SKrishna Gudipati  *  MS State Machine events
2843a36c61f9SKrishna Gudipati  */
2844a36c61f9SKrishna Gudipati enum port_ms_event {
2845a36c61f9SKrishna Gudipati 	MSSM_EVENT_PORT_ONLINE = 1,
2846a36c61f9SKrishna Gudipati 	MSSM_EVENT_PORT_OFFLINE = 2,
2847a36c61f9SKrishna Gudipati 	MSSM_EVENT_RSP_OK = 3,
2848a36c61f9SKrishna Gudipati 	MSSM_EVENT_RSP_ERROR = 4,
2849a36c61f9SKrishna Gudipati 	MSSM_EVENT_TIMEOUT = 5,
2850a36c61f9SKrishna Gudipati 	MSSM_EVENT_FCXP_SENT = 6,
2851a36c61f9SKrishna Gudipati 	MSSM_EVENT_PORT_FABRIC_RSCN = 7
2852a36c61f9SKrishna Gudipati };
2853a36c61f9SKrishna Gudipati 
2854a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2855a36c61f9SKrishna Gudipati 					   enum port_ms_event event);
2856a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2857a36c61f9SKrishna Gudipati 						 enum port_ms_event event);
2858a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2859a36c61f9SKrishna Gudipati 					 enum port_ms_event event);
2860a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2861a36c61f9SKrishna Gudipati 					       enum port_ms_event event);
2862a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2863a36c61f9SKrishna Gudipati 						 enum port_ms_event event);
2864a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2865a36c61f9SKrishna Gudipati 					 enum port_ms_event event);
2866a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2867a36c61f9SKrishna Gudipati 					       enum port_ms_event event);
2868a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
2869a36c61f9SKrishna Gudipati 						 enum port_ms_event event);
2870a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2871a36c61f9SKrishna Gudipati 					 enum port_ms_event event);
2872a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2873a36c61f9SKrishna Gudipati 					       enum port_ms_event event);
2874a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2875a36c61f9SKrishna Gudipati 					  enum port_ms_event event);
28765fbe25c7SJing Huang /*
2877a36c61f9SKrishna Gudipati  *	Start in offline state - awaiting NS to send start.
2878a36c61f9SKrishna Gudipati  */
2879a36c61f9SKrishna Gudipati static void
2880a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2881a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2882a36c61f9SKrishna Gudipati {
2883a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2884a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2885a36c61f9SKrishna Gudipati 
2886a36c61f9SKrishna Gudipati 	switch (event) {
2887a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_ONLINE:
2888a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2889a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_plogi(ms, NULL);
2890a36c61f9SKrishna Gudipati 		break;
2891a36c61f9SKrishna Gudipati 
2892a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2893a36c61f9SKrishna Gudipati 		break;
2894a36c61f9SKrishna Gudipati 
2895a36c61f9SKrishna Gudipati 	default:
2896a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2897a36c61f9SKrishna Gudipati 	}
2898a36c61f9SKrishna Gudipati }
2899a36c61f9SKrishna Gudipati 
2900a36c61f9SKrishna Gudipati static void
2901a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2902a36c61f9SKrishna Gudipati 				enum port_ms_event event)
2903a36c61f9SKrishna Gudipati {
2904a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2905a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2906a36c61f9SKrishna Gudipati 
2907a36c61f9SKrishna Gudipati 	switch (event) {
2908a36c61f9SKrishna Gudipati 	case MSSM_EVENT_FCXP_SENT:
2909a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi);
2910a36c61f9SKrishna Gudipati 		break;
2911a36c61f9SKrishna Gudipati 
2912a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2913a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2914a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2915a36c61f9SKrishna Gudipati 					   &ms->fcxp_wqe);
2916a36c61f9SKrishna Gudipati 		break;
2917a36c61f9SKrishna Gudipati 
2918a36c61f9SKrishna Gudipati 	default:
2919a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2920a36c61f9SKrishna Gudipati 	}
2921a36c61f9SKrishna Gudipati }
2922a36c61f9SKrishna Gudipati 
2923a36c61f9SKrishna Gudipati static void
2924a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2925a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2926a36c61f9SKrishna Gudipati {
2927a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2928a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2929a36c61f9SKrishna Gudipati 
2930a36c61f9SKrishna Gudipati 	switch (event) {
2931a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_ERROR:
2932a36c61f9SKrishna Gudipati 		/*
2933a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
2934a36c61f9SKrishna Gudipati 		 */
2935a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_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 		break;
2941a36c61f9SKrishna Gudipati 
2942a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_OK:
2943a36c61f9SKrishna Gudipati 		/*
2944a36c61f9SKrishna Gudipati 		 * since plogi is done, now invoke MS related sub-modules
2945a36c61f9SKrishna Gudipati 		 */
2946a36c61f9SKrishna Gudipati 		bfa_fcs_lport_fdmi_online(ms);
2947a36c61f9SKrishna Gudipati 
29485fbe25c7SJing Huang 		/*
2949a36c61f9SKrishna Gudipati 		 * if this is a Vport, go to online state.
2950a36c61f9SKrishna Gudipati 		 */
2951a36c61f9SKrishna Gudipati 		if (ms->port->vport) {
2952a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2953a36c61f9SKrishna Gudipati 			break;
2954a36c61f9SKrishna Gudipati 		}
2955a36c61f9SKrishna Gudipati 
2956a36c61f9SKrishna Gudipati 		/*
2957a36c61f9SKrishna Gudipati 		 * For a base port we need to get the
2958a36c61f9SKrishna Gudipati 		 * switch's IP address.
2959a36c61f9SKrishna Gudipati 		 */
2960a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2961a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gmal(ms, NULL);
2962a36c61f9SKrishna Gudipati 		break;
2963a36c61f9SKrishna Gudipati 
2964a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2965a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2966a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ms->fcxp);
2967a36c61f9SKrishna Gudipati 		break;
2968a36c61f9SKrishna Gudipati 
2969a36c61f9SKrishna Gudipati 	default:
2970a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2971a36c61f9SKrishna Gudipati 	}
2972a36c61f9SKrishna Gudipati }
2973a36c61f9SKrishna Gudipati 
2974a36c61f9SKrishna Gudipati static void
2975a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2976a36c61f9SKrishna Gudipati 			enum port_ms_event event)
2977a36c61f9SKrishna Gudipati {
2978a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2979a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
2980a36c61f9SKrishna Gudipati 
2981a36c61f9SKrishna Gudipati 	switch (event) {
2982a36c61f9SKrishna Gudipati 	case MSSM_EVENT_TIMEOUT:
2983a36c61f9SKrishna Gudipati 		/*
2984a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
2985a36c61f9SKrishna Gudipati 		 */
2986a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2987a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_plogi(ms, NULL);
2988a36c61f9SKrishna Gudipati 		break;
2989a36c61f9SKrishna Gudipati 
2990a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
2991a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2992a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ms->timer);
2993a36c61f9SKrishna Gudipati 		break;
2994a36c61f9SKrishna Gudipati 
2995a36c61f9SKrishna Gudipati 	default:
2996a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
2997a36c61f9SKrishna Gudipati 	}
2998a36c61f9SKrishna Gudipati }
2999a36c61f9SKrishna Gudipati 
3000a36c61f9SKrishna Gudipati static void
3001a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
3002a36c61f9SKrishna Gudipati 			enum port_ms_event event)
3003a36c61f9SKrishna Gudipati {
3004a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3005a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
3006a36c61f9SKrishna Gudipati 
3007a36c61f9SKrishna Gudipati 	switch (event) {
3008a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
3009a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3010a36c61f9SKrishna Gudipati 		break;
3011a36c61f9SKrishna Gudipati 
3012a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_FABRIC_RSCN:
3013a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
3014a36c61f9SKrishna Gudipati 		ms->retry_cnt = 0;
3015a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gfn(ms, NULL);
3016a36c61f9SKrishna Gudipati 		break;
3017a36c61f9SKrishna Gudipati 
3018a36c61f9SKrishna Gudipati 	default:
3019a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
3020a36c61f9SKrishna Gudipati 	}
3021a36c61f9SKrishna Gudipati }
3022a36c61f9SKrishna Gudipati 
3023a36c61f9SKrishna Gudipati static void
3024a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
3025a36c61f9SKrishna Gudipati 				enum port_ms_event event)
3026a36c61f9SKrishna Gudipati {
3027a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3028a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
3029a36c61f9SKrishna Gudipati 
3030a36c61f9SKrishna Gudipati 	switch (event) {
3031a36c61f9SKrishna Gudipati 	case MSSM_EVENT_FCXP_SENT:
3032a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal);
3033a36c61f9SKrishna Gudipati 		break;
3034a36c61f9SKrishna Gudipati 
3035a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
3036a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3037a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
3038a36c61f9SKrishna Gudipati 					   &ms->fcxp_wqe);
3039a36c61f9SKrishna Gudipati 		break;
3040a36c61f9SKrishna Gudipati 
3041a36c61f9SKrishna Gudipati 	default:
3042a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
3043a36c61f9SKrishna Gudipati 	}
3044a36c61f9SKrishna Gudipati }
3045a36c61f9SKrishna Gudipati 
3046a36c61f9SKrishna Gudipati static void
3047a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
3048a36c61f9SKrishna Gudipati 				enum port_ms_event event)
3049a36c61f9SKrishna Gudipati {
3050a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3051a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
3052a36c61f9SKrishna Gudipati 
3053a36c61f9SKrishna Gudipati 	switch (event) {
3054a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_ERROR:
3055a36c61f9SKrishna Gudipati 		/*
3056a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3057a36c61f9SKrishna Gudipati 		 */
3058a36c61f9SKrishna Gudipati 		if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
3059a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry);
3060a36c61f9SKrishna Gudipati 			ms->port->stats.ms_retries++;
3061a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
3062a36c61f9SKrishna Gudipati 				&ms->timer, bfa_fcs_lport_ms_timeout, ms,
3063a36c61f9SKrishna Gudipati 				BFA_FCS_RETRY_TIMEOUT);
3064a36c61f9SKrishna Gudipati 		} else {
3065a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
3066a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ms_send_gfn(ms, NULL);
3067a36c61f9SKrishna Gudipati 			ms->retry_cnt = 0;
3068a36c61f9SKrishna Gudipati 		}
3069a36c61f9SKrishna Gudipati 		break;
3070a36c61f9SKrishna Gudipati 
3071a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_OK:
3072a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
3073a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gfn(ms, NULL);
3074a36c61f9SKrishna Gudipati 		break;
3075a36c61f9SKrishna Gudipati 
3076a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
3077a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3078a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ms->fcxp);
3079a36c61f9SKrishna Gudipati 		break;
3080a36c61f9SKrishna Gudipati 
3081a36c61f9SKrishna Gudipati 	default:
3082a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
3083a36c61f9SKrishna Gudipati 	}
3084a36c61f9SKrishna Gudipati }
3085a36c61f9SKrishna Gudipati 
3086a36c61f9SKrishna Gudipati static void
3087a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
3088a36c61f9SKrishna Gudipati 				enum port_ms_event event)
3089a36c61f9SKrishna Gudipati {
3090a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3091a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
3092a36c61f9SKrishna Gudipati 
3093a36c61f9SKrishna Gudipati 	switch (event) {
3094a36c61f9SKrishna Gudipati 	case MSSM_EVENT_TIMEOUT:
3095a36c61f9SKrishna Gudipati 		/*
3096a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
3097a36c61f9SKrishna Gudipati 		 */
3098a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
3099a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gmal(ms, NULL);
3100a36c61f9SKrishna Gudipati 		break;
3101a36c61f9SKrishna Gudipati 
3102a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
3103a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3104a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ms->timer);
3105a36c61f9SKrishna Gudipati 		break;
3106a36c61f9SKrishna Gudipati 
3107a36c61f9SKrishna Gudipati 	default:
3108a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
3109a36c61f9SKrishna Gudipati 	}
3110a36c61f9SKrishna Gudipati }
31115fbe25c7SJing Huang /*
3112a36c61f9SKrishna Gudipati  *  ms_pvt MS local functions
3113a36c61f9SKrishna Gudipati  */
3114a36c61f9SKrishna Gudipati 
3115a36c61f9SKrishna Gudipati static void
3116a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3117a36c61f9SKrishna Gudipati {
3118a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
3119a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
3120a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
3121a36c61f9SKrishna Gudipati 	int		len;
3122a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3123a36c61f9SKrishna Gudipati 
3124a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
3125a36c61f9SKrishna Gudipati 
3126c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
3127c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3128a36c61f9SKrishna Gudipati 	if (!fcxp) {
3129a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3130c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ms_send_gmal, ms, BFA_TRUE);
3131a36c61f9SKrishna Gudipati 		return;
3132a36c61f9SKrishna Gudipati 	}
3133a36c61f9SKrishna Gudipati 	ms->fcxp = fcxp;
3134a36c61f9SKrishna Gudipati 
3135a36c61f9SKrishna Gudipati 	len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3136a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port),
3137f7f73812SMaggie Zhang 				 port->fabric->lps->pr_nwwn);
3138a36c61f9SKrishna Gudipati 
3139a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3140a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3141a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ms_gmal_response, (void *)ms,
3142a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
3143a36c61f9SKrishna Gudipati 
3144a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
3145a36c61f9SKrishna Gudipati }
3146a36c61f9SKrishna Gudipati 
3147a36c61f9SKrishna Gudipati static void
3148a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3149a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
3150a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
3151a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
3152a36c61f9SKrishna Gudipati {
3153a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3154a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
3155a36c61f9SKrishna Gudipati 	struct ct_hdr_s		*cthdr = NULL;
3156a36c61f9SKrishna Gudipati 	struct fcgs_gmal_resp_s *gmal_resp;
3157a36c61f9SKrishna Gudipati 	struct fcgs_gmal_entry_s *gmal_entry;
3158a36c61f9SKrishna Gudipati 	u32		num_entries;
3159a36c61f9SKrishna Gudipati 	u8			*rsp_str;
3160a36c61f9SKrishna Gudipati 
3161a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
3162a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3163a36c61f9SKrishna Gudipati 
3164a36c61f9SKrishna Gudipati 	/*
3165a36c61f9SKrishna Gudipati 	 * Sanity Checks
3166a36c61f9SKrishna Gudipati 	 */
3167a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3168a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
3169a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3170a36c61f9SKrishna Gudipati 		return;
3171a36c61f9SKrishna Gudipati 	}
3172a36c61f9SKrishna Gudipati 
3173a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3174ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3175a36c61f9SKrishna Gudipati 
3176a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3177a36c61f9SKrishna Gudipati 		gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
3178a36c61f9SKrishna Gudipati 
3179ba816ea8SJing Huang 		num_entries = be32_to_cpu(gmal_resp->ms_len);
3180a36c61f9SKrishna Gudipati 		if (num_entries == 0) {
3181a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3182a36c61f9SKrishna Gudipati 			return;
3183a36c61f9SKrishna Gudipati 		}
3184a36c61f9SKrishna Gudipati 		/*
3185a36c61f9SKrishna Gudipati 		* The response could contain multiple Entries.
3186a36c61f9SKrishna Gudipati 		* Entries for SNMP interface, etc.
3187a36c61f9SKrishna Gudipati 		* We look for the entry with a telnet prefix.
3188a36c61f9SKrishna Gudipati 		* First "http://" entry refers to IP addr
3189a36c61f9SKrishna Gudipati 		*/
3190a36c61f9SKrishna Gudipati 
3191a36c61f9SKrishna Gudipati 		gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma;
3192a36c61f9SKrishna Gudipati 		while (num_entries > 0) {
3193a36c61f9SKrishna Gudipati 			if (strncmp(gmal_entry->prefix,
3194a36c61f9SKrishna Gudipati 				CT_GMAL_RESP_PREFIX_HTTP,
3195a36c61f9SKrishna Gudipati 				sizeof(gmal_entry->prefix)) == 0) {
3196a36c61f9SKrishna Gudipati 
3197a36c61f9SKrishna Gudipati 				/*
3198a36c61f9SKrishna Gudipati 				* if the IP address is terminating with a '/',
3199a36c61f9SKrishna Gudipati 				* remove it.
3200a36c61f9SKrishna Gudipati 				* Byte 0 consists of the length of the string.
3201a36c61f9SKrishna Gudipati 				*/
3202a36c61f9SKrishna Gudipati 				rsp_str = &(gmal_entry->prefix[0]);
3203a36c61f9SKrishna Gudipati 				if (rsp_str[gmal_entry->len-1] == '/')
3204a36c61f9SKrishna Gudipati 					rsp_str[gmal_entry->len-1] = 0;
3205a36c61f9SKrishna Gudipati 
3206a36c61f9SKrishna Gudipati 				/* copy IP Address to fabric */
3207a36c61f9SKrishna Gudipati 				strncpy(bfa_fcs_lport_get_fabric_ipaddr(port),
3208a36c61f9SKrishna Gudipati 					gmal_entry->ip_addr,
3209a36c61f9SKrishna Gudipati 					BFA_FCS_FABRIC_IPADDR_SZ);
3210a36c61f9SKrishna Gudipati 				break;
3211a36c61f9SKrishna Gudipati 			} else {
3212a36c61f9SKrishna Gudipati 				--num_entries;
3213a36c61f9SKrishna Gudipati 				++gmal_entry;
3214a36c61f9SKrishna Gudipati 			}
3215a36c61f9SKrishna Gudipati 		}
3216a36c61f9SKrishna Gudipati 
3217a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
3218a36c61f9SKrishna Gudipati 		return;
3219a36c61f9SKrishna Gudipati 	}
3220a36c61f9SKrishna Gudipati 
3221a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
3222a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
3223a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3224a36c61f9SKrishna Gudipati }
3225a36c61f9SKrishna Gudipati 
3226a36c61f9SKrishna Gudipati static void
3227a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
3228a36c61f9SKrishna Gudipati 			enum port_ms_event event)
3229a36c61f9SKrishna Gudipati {
3230a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3231a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
3232a36c61f9SKrishna Gudipati 
3233a36c61f9SKrishna Gudipati 	switch (event) {
3234a36c61f9SKrishna Gudipati 	case MSSM_EVENT_FCXP_SENT:
3235a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn);
3236a36c61f9SKrishna Gudipati 		break;
3237a36c61f9SKrishna Gudipati 
3238a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
3239a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3240a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
3241a36c61f9SKrishna Gudipati 					   &ms->fcxp_wqe);
3242a36c61f9SKrishna Gudipati 		break;
3243a36c61f9SKrishna Gudipati 
3244a36c61f9SKrishna Gudipati 	default:
3245a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
3246a36c61f9SKrishna Gudipati 	}
3247a36c61f9SKrishna Gudipati }
3248a36c61f9SKrishna Gudipati 
3249a36c61f9SKrishna Gudipati static void
3250a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
3251a36c61f9SKrishna Gudipati 			enum port_ms_event event)
3252a36c61f9SKrishna Gudipati {
3253a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3254a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
3255a36c61f9SKrishna Gudipati 
3256a36c61f9SKrishna Gudipati 	switch (event) {
3257a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_ERROR:
3258a36c61f9SKrishna Gudipati 		/*
3259a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3260a36c61f9SKrishna Gudipati 		 */
3261a36c61f9SKrishna Gudipati 		if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
3262a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry);
3263a36c61f9SKrishna Gudipati 			ms->port->stats.ms_retries++;
3264a36c61f9SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
3265a36c61f9SKrishna Gudipati 				&ms->timer, bfa_fcs_lport_ms_timeout, ms,
3266a36c61f9SKrishna Gudipati 				BFA_FCS_RETRY_TIMEOUT);
3267a36c61f9SKrishna Gudipati 		} else {
3268a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
3269a36c61f9SKrishna Gudipati 			ms->retry_cnt = 0;
3270a36c61f9SKrishna Gudipati 		}
3271a36c61f9SKrishna Gudipati 		break;
3272a36c61f9SKrishna Gudipati 
3273a36c61f9SKrishna Gudipati 	case MSSM_EVENT_RSP_OK:
3274a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
3275a36c61f9SKrishna Gudipati 		break;
3276a36c61f9SKrishna Gudipati 
3277a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
3278a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3279a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ms->fcxp);
3280a36c61f9SKrishna Gudipati 		break;
3281a36c61f9SKrishna Gudipati 
3282a36c61f9SKrishna Gudipati 	default:
3283a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
3284a36c61f9SKrishna Gudipati 	}
3285a36c61f9SKrishna Gudipati }
3286a36c61f9SKrishna Gudipati 
3287a36c61f9SKrishna Gudipati static void
3288a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
3289a36c61f9SKrishna Gudipati 				enum port_ms_event event)
3290a36c61f9SKrishna Gudipati {
3291a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3292a36c61f9SKrishna Gudipati 	bfa_trc(ms->port->fcs, event);
3293a36c61f9SKrishna Gudipati 
3294a36c61f9SKrishna Gudipati 	switch (event) {
3295a36c61f9SKrishna Gudipati 	case MSSM_EVENT_TIMEOUT:
3296a36c61f9SKrishna Gudipati 		/*
3297a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
3298a36c61f9SKrishna Gudipati 		 */
3299a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
3300a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_send_gfn(ms, NULL);
3301a36c61f9SKrishna Gudipati 		break;
3302a36c61f9SKrishna Gudipati 
3303a36c61f9SKrishna Gudipati 	case MSSM_EVENT_PORT_OFFLINE:
3304a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3305a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ms->timer);
3306a36c61f9SKrishna Gudipati 		break;
3307a36c61f9SKrishna Gudipati 
3308a36c61f9SKrishna Gudipati 	default:
3309a36c61f9SKrishna Gudipati 		bfa_sm_fault(ms->port->fcs, event);
3310a36c61f9SKrishna Gudipati 	}
3311a36c61f9SKrishna Gudipati }
33125fbe25c7SJing Huang /*
3313a36c61f9SKrishna Gudipati  *  ms_pvt MS local functions
3314a36c61f9SKrishna Gudipati  */
3315a36c61f9SKrishna Gudipati 
3316a36c61f9SKrishna Gudipati static void
3317a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3318a36c61f9SKrishna Gudipati {
3319a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
3320a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
3321a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
3322a36c61f9SKrishna Gudipati 	int			len;
3323a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3324a36c61f9SKrishna Gudipati 
3325a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
3326a36c61f9SKrishna Gudipati 
3327c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
3328c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3329a36c61f9SKrishna Gudipati 	if (!fcxp) {
3330a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3331c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ms_send_gfn, ms, BFA_TRUE);
3332a36c61f9SKrishna Gudipati 		return;
3333a36c61f9SKrishna Gudipati 	}
3334a36c61f9SKrishna Gudipati 	ms->fcxp = fcxp;
3335a36c61f9SKrishna Gudipati 
3336a36c61f9SKrishna Gudipati 	len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3337a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port),
3338f7f73812SMaggie Zhang 				 port->fabric->lps->pr_nwwn);
3339a36c61f9SKrishna Gudipati 
3340a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3341a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3342a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ms_gfn_response, (void *)ms,
3343a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
3344a36c61f9SKrishna Gudipati 
3345a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
3346a36c61f9SKrishna Gudipati }
3347a36c61f9SKrishna Gudipati 
3348a36c61f9SKrishna Gudipati static void
3349a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3350a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
3351a36c61f9SKrishna Gudipati 			u32 resid_len, struct fchs_s *rsp_fchs)
3352a36c61f9SKrishna Gudipati {
3353a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3354a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = ms->port;
3355a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr = NULL;
3356a36c61f9SKrishna Gudipati 	wwn_t	       *gfn_resp;
3357a36c61f9SKrishna Gudipati 
3358a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
3359a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3360a36c61f9SKrishna Gudipati 
3361a36c61f9SKrishna Gudipati 	/*
3362a36c61f9SKrishna Gudipati 	 * Sanity Checks
3363a36c61f9SKrishna Gudipati 	 */
3364a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3365a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
3366a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3367a36c61f9SKrishna Gudipati 		return;
3368a36c61f9SKrishna Gudipati 	}
3369a36c61f9SKrishna Gudipati 
3370a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3371ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3372a36c61f9SKrishna Gudipati 
3373a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3374a36c61f9SKrishna Gudipati 		gfn_resp = (wwn_t *)(cthdr + 1);
3375a36c61f9SKrishna Gudipati 		/* check if it has actually changed */
3376a36c61f9SKrishna Gudipati 		if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port),
3377a36c61f9SKrishna Gudipati 				gfn_resp, sizeof(wwn_t)) != 0)) {
3378a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
3379a36c61f9SKrishna Gudipati 		}
3380a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
3381a36c61f9SKrishna Gudipati 		return;
3382a36c61f9SKrishna Gudipati 	}
3383a36c61f9SKrishna Gudipati 
3384a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
3385a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
3386a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3387a36c61f9SKrishna Gudipati }
3388a36c61f9SKrishna Gudipati 
33895fbe25c7SJing Huang /*
3390a36c61f9SKrishna Gudipati  *  ms_pvt MS local functions
3391a36c61f9SKrishna Gudipati  */
3392a36c61f9SKrishna Gudipati 
3393a36c61f9SKrishna Gudipati static void
3394a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3395a36c61f9SKrishna Gudipati {
3396a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
3397a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ms->port;
3398a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
3399a36c61f9SKrishna Gudipati 	int	len;
3400a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3401a36c61f9SKrishna Gudipati 
3402a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
3403a36c61f9SKrishna Gudipati 
3404c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
3405c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3406a36c61f9SKrishna Gudipati 	if (!fcxp) {
3407a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_alloc_wait++;
3408a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3409c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ms_send_plogi, ms, BFA_TRUE);
3410a36c61f9SKrishna Gudipati 		return;
3411a36c61f9SKrishna Gudipati 	}
3412a36c61f9SKrishna Gudipati 	ms->fcxp = fcxp;
3413a36c61f9SKrishna Gudipati 
3414a36c61f9SKrishna Gudipati 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3415f16a1750SMaggie Zhang 			     bfa_hton3b(FC_MGMT_SERVER),
3416a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port), 0,
3417a36c61f9SKrishna Gudipati 			     port->port_cfg.pwwn, port->port_cfg.nwwn,
3418be540a99SKrishna Gudipati 			     bfa_fcport_get_maxfrsize(port->fcs->bfa),
3419be540a99SKrishna Gudipati 			     bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
3420a36c61f9SKrishna Gudipati 
3421a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3422a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
3423a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ms_plogi_response, (void *)ms,
3424a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_ELS_TOV);
3425a36c61f9SKrishna Gudipati 
3426a36c61f9SKrishna Gudipati 	port->stats.ms_plogi_sent++;
3427a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
3428a36c61f9SKrishna Gudipati }
3429a36c61f9SKrishna Gudipati 
3430a36c61f9SKrishna Gudipati static void
3431a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3432a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status,
3433a36c61f9SKrishna Gudipati 			u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs)
3434a36c61f9SKrishna Gudipati {
3435a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3436a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ms->port;
3437a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd;
3438a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
3439a36c61f9SKrishna Gudipati 
3440a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
3441a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
3442a36c61f9SKrishna Gudipati 
3443a36c61f9SKrishna Gudipati 	/*
3444a36c61f9SKrishna Gudipati 	 * Sanity Checks
3445a36c61f9SKrishna Gudipati 	 */
3446a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3447a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_rsp_err++;
3448a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
3449a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3450a36c61f9SKrishna Gudipati 		return;
3451a36c61f9SKrishna Gudipati 	}
3452a36c61f9SKrishna Gudipati 
3453a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
3454a36c61f9SKrishna Gudipati 
3455a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
3456a36c61f9SKrishna Gudipati 
3457a36c61f9SKrishna Gudipati 	case FC_ELS_ACC:
3458a36c61f9SKrishna Gudipati 		if (rsp_len < sizeof(struct fc_logi_s)) {
3459a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rsp_len);
3460a36c61f9SKrishna Gudipati 			port->stats.ms_plogi_acc_err++;
3461a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3462a36c61f9SKrishna Gudipati 			break;
3463a36c61f9SKrishna Gudipati 		}
3464a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_accepts++;
3465a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
3466a36c61f9SKrishna Gudipati 		break;
3467a36c61f9SKrishna Gudipati 
3468a36c61f9SKrishna Gudipati 	case FC_ELS_LS_RJT:
3469a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3470a36c61f9SKrishna Gudipati 
3471a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code);
3472a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code_expl);
3473a36c61f9SKrishna Gudipati 
3474a36c61f9SKrishna Gudipati 		port->stats.ms_rejects++;
3475a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3476a36c61f9SKrishna Gudipati 		break;
3477a36c61f9SKrishna Gudipati 
3478a36c61f9SKrishna Gudipati 	default:
3479a36c61f9SKrishna Gudipati 		port->stats.ms_plogi_unknown_rsp++;
3480a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, els_cmd->els_code);
3481a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3482a36c61f9SKrishna Gudipati 	}
3483a36c61f9SKrishna Gudipati }
3484a36c61f9SKrishna Gudipati 
3485a36c61f9SKrishna Gudipati static void
3486a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_timeout(void *arg)
3487a36c61f9SKrishna Gudipati {
3488a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg;
3489a36c61f9SKrishna Gudipati 
3490a36c61f9SKrishna Gudipati 	ms->port->stats.ms_timeouts++;
3491a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
3492a36c61f9SKrishna Gudipati }
3493a36c61f9SKrishna Gudipati 
3494a36c61f9SKrishna Gudipati 
3495a36c61f9SKrishna Gudipati void
3496a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port)
3497a36c61f9SKrishna Gudipati {
3498a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3499a36c61f9SKrishna Gudipati 
3500a36c61f9SKrishna Gudipati 	ms->port = port;
3501a36c61f9SKrishna Gudipati 	bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3502a36c61f9SKrishna Gudipati 
3503a36c61f9SKrishna Gudipati 	/*
3504a36c61f9SKrishna Gudipati 	 * Invoke init routines of sub modules.
3505a36c61f9SKrishna Gudipati 	 */
3506a36c61f9SKrishna Gudipati 	bfa_fcs_lport_fdmi_init(ms);
3507a36c61f9SKrishna Gudipati }
3508a36c61f9SKrishna Gudipati 
3509a36c61f9SKrishna Gudipati void
3510a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port)
3511a36c61f9SKrishna Gudipati {
3512a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3513a36c61f9SKrishna Gudipati 
3514a36c61f9SKrishna Gudipati 	ms->port = port;
3515a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
3516a36c61f9SKrishna Gudipati 	bfa_fcs_lport_fdmi_offline(ms);
3517a36c61f9SKrishna Gudipati }
3518a36c61f9SKrishna Gudipati 
3519a36c61f9SKrishna Gudipati void
3520a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port)
3521a36c61f9SKrishna Gudipati {
3522a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3523a36c61f9SKrishna Gudipati 
3524a36c61f9SKrishna Gudipati 	ms->port = port;
3525a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
3526a36c61f9SKrishna Gudipati }
3527a36c61f9SKrishna Gudipati void
3528a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port)
3529a36c61f9SKrishna Gudipati {
3530a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3531a36c61f9SKrishna Gudipati 
3532a36c61f9SKrishna Gudipati 	/* todo.  Handle this only  when in Online state */
3533a36c61f9SKrishna Gudipati 	if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online))
3534a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
3535a36c61f9SKrishna Gudipati }
3536a36c61f9SKrishna Gudipati 
35375fbe25c7SJing Huang /*
3538a36c61f9SKrishna Gudipati  * @page ns_sm_info VPORT NS State Machine
3539a36c61f9SKrishna Gudipati  *
3540a36c61f9SKrishna Gudipati  * @section ns_sm_interactions VPORT NS State Machine Interactions
3541a36c61f9SKrishna Gudipati  *
3542a36c61f9SKrishna Gudipati  * @section ns_sm VPORT NS State Machine
3543a36c61f9SKrishna Gudipati  * img ns_sm.jpg
3544a36c61f9SKrishna Gudipati  */
3545a36c61f9SKrishna Gudipati 
3546a36c61f9SKrishna Gudipati /*
3547a36c61f9SKrishna Gudipati  * forward declarations
3548a36c61f9SKrishna Gudipati  */
3549a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_plogi(void *ns_cbarg,
3550a36c61f9SKrishna Gudipati 					   struct bfa_fcxp_s *fcxp_alloced);
3551a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg,
3552a36c61f9SKrishna Gudipati 					     struct bfa_fcxp_s *fcxp_alloced);
3553a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg,
3554a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
3555a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg,
3556a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
3557a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg,
3558a36c61f9SKrishna Gudipati 					    struct bfa_fcxp_s *fcxp_alloced);
3559ce7242b8SKrishna Gudipati static void	bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg,
3560ce7242b8SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
3561ce7242b8SKrishna Gudipati static void	bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg,
3562ce7242b8SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
3563a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_timeout(void *arg);
3564a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_plogi_response(void *fcsarg,
3565a36c61f9SKrishna Gudipati 					       struct bfa_fcxp_s *fcxp,
3566a36c61f9SKrishna Gudipati 					       void *cbarg,
3567a36c61f9SKrishna Gudipati 					       bfa_status_t req_status,
3568a36c61f9SKrishna Gudipati 					       u32 rsp_len,
3569a36c61f9SKrishna Gudipati 					       u32 resid_len,
3570a36c61f9SKrishna Gudipati 					       struct fchs_s *rsp_fchs);
3571a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_rspn_id_response(void *fcsarg,
3572a36c61f9SKrishna Gudipati 						 struct bfa_fcxp_s *fcxp,
3573a36c61f9SKrishna Gudipati 						 void *cbarg,
3574a36c61f9SKrishna Gudipati 						 bfa_status_t req_status,
3575a36c61f9SKrishna Gudipati 						 u32 rsp_len,
3576a36c61f9SKrishna Gudipati 						 u32 resid_len,
3577a36c61f9SKrishna Gudipati 						 struct fchs_s *rsp_fchs);
3578a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_rft_id_response(void *fcsarg,
3579a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3580a36c61f9SKrishna Gudipati 						void *cbarg,
3581a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
3582a36c61f9SKrishna Gudipati 						u32 rsp_len,
3583a36c61f9SKrishna Gudipati 						u32 resid_len,
3584a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3585a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_rff_id_response(void *fcsarg,
3586a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3587a36c61f9SKrishna Gudipati 						void *cbarg,
3588a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
3589a36c61f9SKrishna Gudipati 						u32 rsp_len,
3590a36c61f9SKrishna Gudipati 						u32 resid_len,
3591a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3592a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_gid_ft_response(void *fcsarg,
3593a36c61f9SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3594a36c61f9SKrishna Gudipati 						void *cbarg,
3595a36c61f9SKrishna Gudipati 						bfa_status_t req_status,
3596a36c61f9SKrishna Gudipati 						u32 rsp_len,
3597a36c61f9SKrishna Gudipati 						u32 resid_len,
3598a36c61f9SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3599ce7242b8SKrishna Gudipati static void     bfa_fcs_lport_ns_rnn_id_response(void *fcsarg,
3600ce7242b8SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3601ce7242b8SKrishna Gudipati 						void *cbarg,
3602ce7242b8SKrishna Gudipati 						bfa_status_t req_status,
3603ce7242b8SKrishna Gudipati 						u32 rsp_len,
3604ce7242b8SKrishna Gudipati 						u32 resid_len,
3605ce7242b8SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3606ce7242b8SKrishna Gudipati static void     bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg,
3607ce7242b8SKrishna Gudipati 						struct bfa_fcxp_s *fcxp,
3608ce7242b8SKrishna Gudipati 						void *cbarg,
3609ce7242b8SKrishna Gudipati 						bfa_status_t req_status,
3610ce7242b8SKrishna Gudipati 						u32 rsp_len,
3611ce7242b8SKrishna Gudipati 						u32 resid_len,
3612ce7242b8SKrishna Gudipati 						struct fchs_s *rsp_fchs);
3613a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_process_gidft_pids(
3614a36c61f9SKrishna Gudipati 				struct bfa_fcs_lport_s *port,
3615a36c61f9SKrishna Gudipati 				u32 *pid_buf, u32 n_pids);
3616a36c61f9SKrishna Gudipati 
3617a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port);
36185fbe25c7SJing Huang /*
3619a36c61f9SKrishna Gudipati  *  fcs_ns_sm FCS nameserver interface state machine
3620a36c61f9SKrishna Gudipati  */
3621a36c61f9SKrishna Gudipati 
36225fbe25c7SJing Huang /*
3623a36c61f9SKrishna Gudipati  * VPort NS State Machine events
3624a36c61f9SKrishna Gudipati  */
3625a36c61f9SKrishna Gudipati enum vport_ns_event {
3626a36c61f9SKrishna Gudipati 	NSSM_EVENT_PORT_ONLINE = 1,
3627a36c61f9SKrishna Gudipati 	NSSM_EVENT_PORT_OFFLINE = 2,
3628a36c61f9SKrishna Gudipati 	NSSM_EVENT_PLOGI_SENT = 3,
3629a36c61f9SKrishna Gudipati 	NSSM_EVENT_RSP_OK = 4,
3630a36c61f9SKrishna Gudipati 	NSSM_EVENT_RSP_ERROR = 5,
3631a36c61f9SKrishna Gudipati 	NSSM_EVENT_TIMEOUT = 6,
3632a36c61f9SKrishna Gudipati 	NSSM_EVENT_NS_QUERY = 7,
3633a36c61f9SKrishna Gudipati 	NSSM_EVENT_RSPNID_SENT = 8,
3634a36c61f9SKrishna Gudipati 	NSSM_EVENT_RFTID_SENT = 9,
3635a36c61f9SKrishna Gudipati 	NSSM_EVENT_RFFID_SENT = 10,
3636a36c61f9SKrishna Gudipati 	NSSM_EVENT_GIDFT_SENT = 11,
3637ce7242b8SKrishna Gudipati 	NSSM_EVENT_RNNID_SENT = 12,
3638ce7242b8SKrishna Gudipati 	NSSM_EVENT_RSNN_NN_SENT = 13,
3639a36c61f9SKrishna Gudipati };
3640a36c61f9SKrishna Gudipati 
3641a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3642a36c61f9SKrishna Gudipati 					   enum vport_ns_event event);
3643a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3644a36c61f9SKrishna Gudipati 						 enum vport_ns_event event);
3645a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3646a36c61f9SKrishna Gudipati 					 enum vport_ns_event event);
3647a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3648a36c61f9SKrishna Gudipati 					       enum vport_ns_event event);
3649a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rspn_id(
3650a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3651a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3652a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3653a36c61f9SKrishna Gudipati 					   enum vport_ns_event event);
3654a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3655a36c61f9SKrishna Gudipati 						 enum vport_ns_event event);
3656a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rft_id(
3657a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3658a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3659a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3660a36c61f9SKrishna Gudipati 						enum vport_ns_event event);
3661a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3662a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
3663a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rff_id(
3664a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3665a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3666a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3667a36c61f9SKrishna Gudipati 						enum vport_ns_event event);
3668a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3669a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
3670a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_gid_ft(
3671a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3672a36c61f9SKrishna Gudipati 					enum vport_ns_event event);
3673a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3674a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
3675a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3676a36c61f9SKrishna Gudipati 						enum vport_ns_event event);
3677a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3678a36c61f9SKrishna Gudipati 					  enum vport_ns_event event);
3679ce7242b8SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rnn_id(
3680ce7242b8SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3681ce7242b8SKrishna Gudipati 					enum vport_ns_event event);
3682ce7242b8SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns,
3683ce7242b8SKrishna Gudipati 					enum vport_ns_event event);
3684ce7242b8SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3685ce7242b8SKrishna Gudipati 						enum vport_ns_event event);
3686ce7242b8SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_sending_rsnn_nn(
3687ce7242b8SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3688ce7242b8SKrishna Gudipati 					enum vport_ns_event event);
3689ce7242b8SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
3690ce7242b8SKrishna Gudipati 						enum vport_ns_event event);
3691ce7242b8SKrishna Gudipati static void     bfa_fcs_lport_ns_sm_rsnn_nn_retry(
3692ce7242b8SKrishna Gudipati 					struct bfa_fcs_lport_ns_s *ns,
3693ce7242b8SKrishna Gudipati 					enum vport_ns_event event);
36945fbe25c7SJing Huang /*
3695a36c61f9SKrishna Gudipati  *	Start in offline state - awaiting linkup
3696a36c61f9SKrishna Gudipati  */
3697a36c61f9SKrishna Gudipati static void
3698a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3699a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3700a36c61f9SKrishna Gudipati {
3701a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3702a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3703a36c61f9SKrishna Gudipati 
3704a36c61f9SKrishna Gudipati 	switch (event) {
3705a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_ONLINE:
3706a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3707a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_plogi(ns, NULL);
3708a36c61f9SKrishna Gudipati 		break;
3709a36c61f9SKrishna Gudipati 
3710a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3711a36c61f9SKrishna Gudipati 		break;
3712a36c61f9SKrishna Gudipati 
3713a36c61f9SKrishna Gudipati 	default:
3714a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3715a36c61f9SKrishna Gudipati 	}
3716a36c61f9SKrishna Gudipati }
3717a36c61f9SKrishna Gudipati 
3718a36c61f9SKrishna Gudipati static void
3719a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3720a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3721a36c61f9SKrishna Gudipati {
3722a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3723a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3724a36c61f9SKrishna Gudipati 
3725a36c61f9SKrishna Gudipati 	switch (event) {
3726a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PLOGI_SENT:
3727a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi);
3728a36c61f9SKrishna Gudipati 		break;
3729a36c61f9SKrishna Gudipati 
3730a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3731a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3732a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3733a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3734a36c61f9SKrishna Gudipati 		break;
3735a36c61f9SKrishna Gudipati 
3736a36c61f9SKrishna Gudipati 	default:
3737a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3738a36c61f9SKrishna Gudipati 	}
3739a36c61f9SKrishna Gudipati }
3740a36c61f9SKrishna Gudipati 
3741a36c61f9SKrishna Gudipati static void
3742a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3743a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3744a36c61f9SKrishna Gudipati {
3745a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3746a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3747a36c61f9SKrishna Gudipati 
3748a36c61f9SKrishna Gudipati 	switch (event) {
3749a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3750a36c61f9SKrishna Gudipati 		/*
3751a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
3752a36c61f9SKrishna Gudipati 		 */
3753a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry);
3754a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
3755a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3756a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3757a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
3758a36c61f9SKrishna Gudipati 		break;
3759a36c61f9SKrishna Gudipati 
3760a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3761ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id);
3762ce7242b8SKrishna Gudipati 		ns->num_rnnid_retries = 0;
3763ce7242b8SKrishna Gudipati 		bfa_fcs_lport_ns_send_rnn_id(ns, NULL);
3764a36c61f9SKrishna Gudipati 		break;
3765a36c61f9SKrishna Gudipati 
3766a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3767a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3768a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3769a36c61f9SKrishna Gudipati 		break;
3770a36c61f9SKrishna Gudipati 
3771a36c61f9SKrishna Gudipati 	default:
3772a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3773a36c61f9SKrishna Gudipati 	}
3774a36c61f9SKrishna Gudipati }
3775a36c61f9SKrishna Gudipati 
3776a36c61f9SKrishna Gudipati static void
3777a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3778a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
3779a36c61f9SKrishna Gudipati {
3780a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3781a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3782a36c61f9SKrishna Gudipati 
3783a36c61f9SKrishna Gudipati 	switch (event) {
3784a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3785a36c61f9SKrishna Gudipati 		/*
3786a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
3787a36c61f9SKrishna Gudipati 		 */
3788a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3789a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_plogi(ns, NULL);
3790a36c61f9SKrishna Gudipati 		break;
3791a36c61f9SKrishna Gudipati 
3792a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3793a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3794a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3795a36c61f9SKrishna Gudipati 		break;
3796a36c61f9SKrishna Gudipati 
3797a36c61f9SKrishna Gudipati 	default:
3798a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3799a36c61f9SKrishna Gudipati 	}
3800a36c61f9SKrishna Gudipati }
3801a36c61f9SKrishna Gudipati 
3802a36c61f9SKrishna Gudipati static void
3803ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rnn_id(struct bfa_fcs_lport_ns_s *ns,
3804ce7242b8SKrishna Gudipati 					enum vport_ns_event event)
3805ce7242b8SKrishna Gudipati {
3806ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3807ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3808ce7242b8SKrishna Gudipati 
3809ce7242b8SKrishna Gudipati 	switch (event) {
3810ce7242b8SKrishna Gudipati 	case NSSM_EVENT_RNNID_SENT:
3811ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id);
3812ce7242b8SKrishna Gudipati 		break;
3813ce7242b8SKrishna Gudipati 
3814ce7242b8SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3815ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3816ce7242b8SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3817ce7242b8SKrishna Gudipati 						&ns->fcxp_wqe);
3818ce7242b8SKrishna Gudipati 		break;
3819ce7242b8SKrishna Gudipati 	default:
3820ce7242b8SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3821ce7242b8SKrishna Gudipati 	}
3822ce7242b8SKrishna Gudipati }
3823ce7242b8SKrishna Gudipati 
3824ce7242b8SKrishna Gudipati static void
3825ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns,
3826ce7242b8SKrishna Gudipati 				enum vport_ns_event event)
3827ce7242b8SKrishna Gudipati {
3828ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3829ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3830ce7242b8SKrishna Gudipati 
3831ce7242b8SKrishna Gudipati 	switch (event) {
3832ce7242b8SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3833ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn);
3834ce7242b8SKrishna Gudipati 		ns->num_rnnid_retries = 0;
3835ce7242b8SKrishna Gudipati 		ns->num_rsnn_nn_retries = 0;
3836ce7242b8SKrishna Gudipati 		bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL);
3837ce7242b8SKrishna Gudipati 		break;
3838ce7242b8SKrishna Gudipati 
3839ce7242b8SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3840ce7242b8SKrishna Gudipati 		if (ns->num_rnnid_retries < BFA_FCS_MAX_NS_RETRIES) {
3841ce7242b8SKrishna Gudipati 			bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id_retry);
3842ce7242b8SKrishna Gudipati 			ns->port->stats.ns_retries++;
3843ce7242b8SKrishna Gudipati 			ns->num_rnnid_retries++;
3844ce7242b8SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3845ce7242b8SKrishna Gudipati 				&ns->timer, bfa_fcs_lport_ns_timeout, ns,
3846ce7242b8SKrishna Gudipati 				BFA_FCS_RETRY_TIMEOUT);
3847ce7242b8SKrishna Gudipati 		} else {
3848ce7242b8SKrishna Gudipati 			bfa_sm_set_state(ns,
3849ce7242b8SKrishna Gudipati 				bfa_fcs_lport_ns_sm_sending_rspn_id);
3850ce7242b8SKrishna Gudipati 			bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3851ce7242b8SKrishna Gudipati 		}
3852ce7242b8SKrishna Gudipati 		break;
3853ce7242b8SKrishna Gudipati 
3854ce7242b8SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3855ce7242b8SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3856ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3857ce7242b8SKrishna Gudipati 		break;
3858ce7242b8SKrishna Gudipati 
3859ce7242b8SKrishna Gudipati 	default:
3860ce7242b8SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3861ce7242b8SKrishna Gudipati 	}
3862ce7242b8SKrishna Gudipati }
3863ce7242b8SKrishna Gudipati 
3864ce7242b8SKrishna Gudipati static void
3865ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3866ce7242b8SKrishna Gudipati 				enum vport_ns_event event)
3867ce7242b8SKrishna Gudipati {
3868ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3869ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3870ce7242b8SKrishna Gudipati 
3871ce7242b8SKrishna Gudipati 	switch (event) {
3872ce7242b8SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3873ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id);
3874ce7242b8SKrishna Gudipati 		bfa_fcs_lport_ns_send_rnn_id(ns, NULL);
3875ce7242b8SKrishna Gudipati 		break;
3876ce7242b8SKrishna Gudipati 
3877ce7242b8SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3878ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3879ce7242b8SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3880ce7242b8SKrishna Gudipati 		break;
3881ce7242b8SKrishna Gudipati 
3882ce7242b8SKrishna Gudipati 	default:
3883ce7242b8SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3884ce7242b8SKrishna Gudipati 	}
3885ce7242b8SKrishna Gudipati }
3886ce7242b8SKrishna Gudipati 
3887ce7242b8SKrishna Gudipati static void
3888ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
3889ce7242b8SKrishna Gudipati 					enum vport_ns_event event)
3890ce7242b8SKrishna Gudipati {
3891ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3892ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3893ce7242b8SKrishna Gudipati 
3894ce7242b8SKrishna Gudipati 	switch (event) {
3895ce7242b8SKrishna Gudipati 	case NSSM_EVENT_RSNN_NN_SENT:
3896ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn);
3897ce7242b8SKrishna Gudipati 		break;
3898ce7242b8SKrishna Gudipati 
3899ce7242b8SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3900ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3901ce7242b8SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3902ce7242b8SKrishna Gudipati 			&ns->fcxp_wqe);
3903ce7242b8SKrishna Gudipati 		break;
3904ce7242b8SKrishna Gudipati 
3905ce7242b8SKrishna Gudipati 	default:
3906ce7242b8SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3907ce7242b8SKrishna Gudipati 	}
3908ce7242b8SKrishna Gudipati }
3909ce7242b8SKrishna Gudipati 
3910ce7242b8SKrishna Gudipati static void
3911ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
3912ce7242b8SKrishna Gudipati 				enum vport_ns_event event)
3913ce7242b8SKrishna Gudipati {
3914ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3915ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3916ce7242b8SKrishna Gudipati 
3917ce7242b8SKrishna Gudipati 	switch (event) {
3918ce7242b8SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
3919ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3920ce7242b8SKrishna Gudipati 		ns->num_rsnn_nn_retries = 0;
3921ce7242b8SKrishna Gudipati 		bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3922ce7242b8SKrishna Gudipati 		break;
3923ce7242b8SKrishna Gudipati 
3924ce7242b8SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
3925ce7242b8SKrishna Gudipati 		if (ns->num_rsnn_nn_retries < BFA_FCS_MAX_NS_RETRIES) {
3926ce7242b8SKrishna Gudipati 			bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn_retry);
3927ce7242b8SKrishna Gudipati 			ns->port->stats.ns_retries++;
3928ce7242b8SKrishna Gudipati 			ns->num_rsnn_nn_retries++;
3929ce7242b8SKrishna Gudipati 			bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3930ce7242b8SKrishna Gudipati 					&ns->timer, bfa_fcs_lport_ns_timeout,
3931ce7242b8SKrishna Gudipati 					ns, BFA_FCS_RETRY_TIMEOUT);
3932ce7242b8SKrishna Gudipati 		} else {
3933ce7242b8SKrishna Gudipati 			bfa_sm_set_state(ns,
3934ce7242b8SKrishna Gudipati 				bfa_fcs_lport_ns_sm_sending_rspn_id);
3935ce7242b8SKrishna Gudipati 			bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3936ce7242b8SKrishna Gudipati 		}
3937ce7242b8SKrishna Gudipati 		break;
3938ce7242b8SKrishna Gudipati 
3939ce7242b8SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3940ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3941ce7242b8SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
3942ce7242b8SKrishna Gudipati 		break;
3943ce7242b8SKrishna Gudipati 
3944ce7242b8SKrishna Gudipati 	default:
3945ce7242b8SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3946ce7242b8SKrishna Gudipati 	}
3947ce7242b8SKrishna Gudipati }
3948ce7242b8SKrishna Gudipati 
3949ce7242b8SKrishna Gudipati static void
3950ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_sm_rsnn_nn_retry(struct bfa_fcs_lport_ns_s *ns,
3951ce7242b8SKrishna Gudipati 					enum vport_ns_event event)
3952ce7242b8SKrishna Gudipati {
3953ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3954ce7242b8SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3955ce7242b8SKrishna Gudipati 
3956ce7242b8SKrishna Gudipati 	switch (event) {
3957ce7242b8SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
3958ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn);
3959ce7242b8SKrishna Gudipati 		bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL);
3960ce7242b8SKrishna Gudipati 		break;
3961ce7242b8SKrishna Gudipati 
3962ce7242b8SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3963ce7242b8SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3964ce7242b8SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
3965ce7242b8SKrishna Gudipati 		break;
3966ce7242b8SKrishna Gudipati 
3967ce7242b8SKrishna Gudipati 	default:
3968ce7242b8SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3969ce7242b8SKrishna Gudipati 	}
3970ce7242b8SKrishna Gudipati }
3971ce7242b8SKrishna Gudipati 
3972ce7242b8SKrishna Gudipati static void
3973a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3974a36c61f9SKrishna Gudipati 				   enum vport_ns_event event)
3975a36c61f9SKrishna Gudipati {
3976a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3977a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
3978a36c61f9SKrishna Gudipati 
3979a36c61f9SKrishna Gudipati 	switch (event) {
3980a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSPNID_SENT:
3981a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id);
3982a36c61f9SKrishna Gudipati 		break;
3983a36c61f9SKrishna Gudipati 
3984a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
3985a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3986a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3987a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
3988a36c61f9SKrishna Gudipati 		break;
3989a36c61f9SKrishna Gudipati 
3990a36c61f9SKrishna Gudipati 	default:
3991a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
3992a36c61f9SKrishna Gudipati 	}
3993a36c61f9SKrishna Gudipati }
3994a36c61f9SKrishna Gudipati 
3995a36c61f9SKrishna Gudipati static void
3996a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3997a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
3998a36c61f9SKrishna Gudipati {
3999a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4000a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4001a36c61f9SKrishna Gudipati 
4002a36c61f9SKrishna Gudipati 	switch (event) {
4003a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
4004a36c61f9SKrishna Gudipati 		/*
4005a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
4006a36c61f9SKrishna Gudipati 		 */
4007a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry);
4008a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
4009a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4010a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
4011a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
4012a36c61f9SKrishna Gudipati 		break;
4013a36c61f9SKrishna Gudipati 
4014a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
4015a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
4016a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rft_id(ns, NULL);
4017a36c61f9SKrishna Gudipati 		break;
4018a36c61f9SKrishna Gudipati 
4019a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4020a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
4021a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4022a36c61f9SKrishna Gudipati 		break;
4023a36c61f9SKrishna Gudipati 
4024a36c61f9SKrishna Gudipati 	default:
4025a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4026a36c61f9SKrishna Gudipati 	}
4027a36c61f9SKrishna Gudipati }
4028a36c61f9SKrishna Gudipati 
4029a36c61f9SKrishna Gudipati static void
4030a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
4031a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
4032a36c61f9SKrishna Gudipati {
4033a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4034a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4035a36c61f9SKrishna Gudipati 
4036a36c61f9SKrishna Gudipati 	switch (event) {
4037a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
4038a36c61f9SKrishna Gudipati 		/*
4039a36c61f9SKrishna Gudipati 		 * Retry Timer Expired. Re-send
4040a36c61f9SKrishna Gudipati 		 */
4041a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
4042a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
4043a36c61f9SKrishna Gudipati 		break;
4044a36c61f9SKrishna Gudipati 
4045a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4046a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4047a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
4048a36c61f9SKrishna Gudipati 		break;
4049a36c61f9SKrishna Gudipati 
4050a36c61f9SKrishna Gudipati 	default:
4051a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4052a36c61f9SKrishna Gudipati 	}
4053a36c61f9SKrishna Gudipati }
4054a36c61f9SKrishna Gudipati 
4055a36c61f9SKrishna Gudipati static void
4056a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns,
4057a36c61f9SKrishna Gudipati 				  enum vport_ns_event event)
4058a36c61f9SKrishna Gudipati {
4059a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4060a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4061a36c61f9SKrishna Gudipati 
4062a36c61f9SKrishna Gudipati 	switch (event) {
4063a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RFTID_SENT:
4064a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id);
4065a36c61f9SKrishna Gudipati 		break;
4066a36c61f9SKrishna Gudipati 
4067a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4068a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4069a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4070a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
4071a36c61f9SKrishna Gudipati 		break;
4072a36c61f9SKrishna Gudipati 
4073a36c61f9SKrishna Gudipati 	default:
4074a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4075a36c61f9SKrishna Gudipati 	}
4076a36c61f9SKrishna Gudipati }
4077a36c61f9SKrishna Gudipati 
4078a36c61f9SKrishna Gudipati static void
4079a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
4080a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
4081a36c61f9SKrishna Gudipati {
4082a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4083a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4084a36c61f9SKrishna Gudipati 
4085a36c61f9SKrishna Gudipati 	switch (event) {
4086a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
4087a36c61f9SKrishna Gudipati 		/* Now move to register FC4 Features */
4088a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
4089a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rff_id(ns, NULL);
4090a36c61f9SKrishna Gudipati 		break;
4091a36c61f9SKrishna Gudipati 
4092a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
4093a36c61f9SKrishna Gudipati 		/*
4094a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
4095a36c61f9SKrishna Gudipati 		 */
4096a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry);
4097a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
4098a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4099a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
4100a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
4101a36c61f9SKrishna Gudipati 		break;
4102a36c61f9SKrishna Gudipati 
4103a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4104a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4105a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
4106a36c61f9SKrishna Gudipati 		break;
4107a36c61f9SKrishna Gudipati 
4108a36c61f9SKrishna Gudipati 	default:
4109a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4110a36c61f9SKrishna Gudipati 	}
4111a36c61f9SKrishna Gudipati }
4112a36c61f9SKrishna Gudipati 
4113a36c61f9SKrishna Gudipati static void
4114a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
4115a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
4116a36c61f9SKrishna Gudipati {
4117a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4118a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4119a36c61f9SKrishna Gudipati 
4120a36c61f9SKrishna Gudipati 	switch (event) {
4121a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
4122a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
4123a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rft_id(ns, NULL);
4124a36c61f9SKrishna Gudipati 		break;
4125a36c61f9SKrishna Gudipati 
4126a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4127a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4128a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
4129a36c61f9SKrishna Gudipati 		break;
4130a36c61f9SKrishna Gudipati 
4131a36c61f9SKrishna Gudipati 	default:
4132a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4133a36c61f9SKrishna Gudipati 	}
4134a36c61f9SKrishna Gudipati }
4135a36c61f9SKrishna Gudipati 
4136a36c61f9SKrishna Gudipati static void
4137a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns,
4138a36c61f9SKrishna Gudipati 				  enum vport_ns_event event)
4139a36c61f9SKrishna Gudipati {
4140a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4141a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4142a36c61f9SKrishna Gudipati 
4143a36c61f9SKrishna Gudipati 	switch (event) {
4144a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RFFID_SENT:
4145a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id);
4146a36c61f9SKrishna Gudipati 		break;
4147a36c61f9SKrishna Gudipati 
4148a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4149a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4150a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4151a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
4152a36c61f9SKrishna Gudipati 		break;
4153a36c61f9SKrishna Gudipati 
4154a36c61f9SKrishna Gudipati 	default:
4155a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4156a36c61f9SKrishna Gudipati 	}
4157a36c61f9SKrishna Gudipati }
4158a36c61f9SKrishna Gudipati 
4159a36c61f9SKrishna Gudipati static void
4160a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
4161a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
4162a36c61f9SKrishna Gudipati {
4163a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4164a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4165a36c61f9SKrishna Gudipati 
4166a36c61f9SKrishna Gudipati 	switch (event) {
4167a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
4168a36c61f9SKrishna Gudipati 
4169a36c61f9SKrishna Gudipati 		/*
4170a36c61f9SKrishna Gudipati 		 * If min cfg mode is enabled, we donot initiate rport
4171a36c61f9SKrishna Gudipati 		 * discovery with the fabric. Instead, we will retrieve the
4172a36c61f9SKrishna Gudipati 		 * boot targets from HAL/FW.
4173a36c61f9SKrishna Gudipati 		 */
4174a36c61f9SKrishna Gudipati 		if (__fcs_min_cfg(ns->port->fcs)) {
4175a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ns_boot_target_disc(ns->port);
4176a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
4177a36c61f9SKrishna Gudipati 			return;
4178a36c61f9SKrishna Gudipati 		}
4179a36c61f9SKrishna Gudipati 
4180a36c61f9SKrishna Gudipati 		/*
4181a36c61f9SKrishna Gudipati 		 * If the port role is Initiator Mode issue NS query.
4182a36c61f9SKrishna Gudipati 		 * If it is Target Mode, skip this and go to online.
4183a36c61f9SKrishna Gudipati 		 */
4184a36c61f9SKrishna Gudipati 		if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
4185a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ns,
4186a36c61f9SKrishna Gudipati 				bfa_fcs_lport_ns_sm_sending_gid_ft);
4187a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
4188a36c61f9SKrishna Gudipati 		}
4189a36c61f9SKrishna Gudipati 		/*
4190a36c61f9SKrishna Gudipati 		 * kick off mgmt srvr state machine
4191a36c61f9SKrishna Gudipati 		 */
4192a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ms_online(ns->port);
4193a36c61f9SKrishna Gudipati 		break;
4194a36c61f9SKrishna Gudipati 
4195a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
4196a36c61f9SKrishna Gudipati 		/*
4197a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
4198a36c61f9SKrishna Gudipati 		 */
4199a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry);
4200a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
4201a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4202a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
4203a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
4204a36c61f9SKrishna Gudipati 		break;
4205a36c61f9SKrishna Gudipati 
4206a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4207a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4208a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
4209a36c61f9SKrishna Gudipati 		break;
4210a36c61f9SKrishna Gudipati 
4211a36c61f9SKrishna Gudipati 	default:
4212a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4213a36c61f9SKrishna Gudipati 	}
4214a36c61f9SKrishna Gudipati }
4215a36c61f9SKrishna Gudipati 
4216a36c61f9SKrishna Gudipati static void
4217a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
4218a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
4219a36c61f9SKrishna Gudipati {
4220a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4221a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4222a36c61f9SKrishna Gudipati 
4223a36c61f9SKrishna Gudipati 	switch (event) {
4224a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
4225a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
4226a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_rff_id(ns, NULL);
4227a36c61f9SKrishna Gudipati 		break;
4228a36c61f9SKrishna Gudipati 
4229a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4230a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4231a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
4232a36c61f9SKrishna Gudipati 		break;
4233a36c61f9SKrishna Gudipati 
4234a36c61f9SKrishna Gudipati 	default:
4235a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4236a36c61f9SKrishna Gudipati 	}
4237a36c61f9SKrishna Gudipati }
4238a36c61f9SKrishna Gudipati static void
4239a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns,
4240a36c61f9SKrishna Gudipati 				  enum vport_ns_event event)
4241a36c61f9SKrishna Gudipati {
4242a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4243a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4244a36c61f9SKrishna Gudipati 
4245a36c61f9SKrishna Gudipati 	switch (event) {
4246a36c61f9SKrishna Gudipati 	case NSSM_EVENT_GIDFT_SENT:
4247a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft);
4248a36c61f9SKrishna Gudipati 		break;
4249a36c61f9SKrishna Gudipati 
4250a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4251a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4252a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4253a36c61f9SKrishna Gudipati 					   &ns->fcxp_wqe);
4254a36c61f9SKrishna Gudipati 		break;
4255a36c61f9SKrishna Gudipati 
4256a36c61f9SKrishna Gudipati 	default:
4257a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4258a36c61f9SKrishna Gudipati 	}
4259a36c61f9SKrishna Gudipati }
4260a36c61f9SKrishna Gudipati 
4261a36c61f9SKrishna Gudipati static void
4262a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
4263a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
4264a36c61f9SKrishna Gudipati {
4265a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4266a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4267a36c61f9SKrishna Gudipati 
4268a36c61f9SKrishna Gudipati 	switch (event) {
4269a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_OK:
4270a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
4271a36c61f9SKrishna Gudipati 		break;
4272a36c61f9SKrishna Gudipati 
4273a36c61f9SKrishna Gudipati 	case NSSM_EVENT_RSP_ERROR:
4274a36c61f9SKrishna Gudipati 		/*
4275a36c61f9SKrishna Gudipati 		 * TBD: for certain reject codes, we don't need to retry
4276a36c61f9SKrishna Gudipati 		 */
4277a36c61f9SKrishna Gudipati 		/*
4278a36c61f9SKrishna Gudipati 		 * Start timer for a delayed retry
4279a36c61f9SKrishna Gudipati 		 */
4280a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry);
4281a36c61f9SKrishna Gudipati 		ns->port->stats.ns_retries++;
4282a36c61f9SKrishna Gudipati 		bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4283a36c61f9SKrishna Gudipati 				    &ns->timer, bfa_fcs_lport_ns_timeout, ns,
4284a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
4285a36c61f9SKrishna Gudipati 		break;
4286a36c61f9SKrishna Gudipati 
4287a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4288a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4289a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(ns->fcxp);
4290a36c61f9SKrishna Gudipati 		break;
4291a36c61f9SKrishna Gudipati 
4292a36c61f9SKrishna Gudipati 	case  NSSM_EVENT_NS_QUERY:
4293a36c61f9SKrishna Gudipati 		break;
4294a36c61f9SKrishna Gudipati 
4295a36c61f9SKrishna Gudipati 	default:
4296a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4297a36c61f9SKrishna Gudipati 	}
4298a36c61f9SKrishna Gudipati }
4299a36c61f9SKrishna Gudipati 
4300a36c61f9SKrishna Gudipati static void
4301a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
4302a36c61f9SKrishna Gudipati 				enum vport_ns_event event)
4303a36c61f9SKrishna Gudipati {
4304a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4305a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4306a36c61f9SKrishna Gudipati 
4307a36c61f9SKrishna Gudipati 	switch (event) {
4308a36c61f9SKrishna Gudipati 	case NSSM_EVENT_TIMEOUT:
4309a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft);
4310a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
4311a36c61f9SKrishna Gudipati 		break;
4312a36c61f9SKrishna Gudipati 
4313a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4314a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4315a36c61f9SKrishna Gudipati 		bfa_timer_stop(&ns->timer);
4316a36c61f9SKrishna Gudipati 		break;
4317a36c61f9SKrishna Gudipati 
4318a36c61f9SKrishna Gudipati 	default:
4319a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4320a36c61f9SKrishna Gudipati 	}
4321a36c61f9SKrishna Gudipati }
4322a36c61f9SKrishna Gudipati 
4323a36c61f9SKrishna Gudipati static void
4324a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
4325a36c61f9SKrishna Gudipati 			enum vport_ns_event event)
4326a36c61f9SKrishna Gudipati {
4327a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4328a36c61f9SKrishna Gudipati 	bfa_trc(ns->port->fcs, event);
4329a36c61f9SKrishna Gudipati 
4330a36c61f9SKrishna Gudipati 	switch (event) {
4331a36c61f9SKrishna Gudipati 	case NSSM_EVENT_PORT_OFFLINE:
4332a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4333a36c61f9SKrishna Gudipati 		break;
4334a36c61f9SKrishna Gudipati 
4335a36c61f9SKrishna Gudipati 	case NSSM_EVENT_NS_QUERY:
4336a36c61f9SKrishna Gudipati 		/*
4337a36c61f9SKrishna Gudipati 		 * If the port role is Initiator Mode issue NS query.
4338a36c61f9SKrishna Gudipati 		 * If it is Target Mode, skip this and go to online.
4339a36c61f9SKrishna Gudipati 		 */
4340a36c61f9SKrishna Gudipati 		if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
4341a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ns,
4342a36c61f9SKrishna Gudipati 				bfa_fcs_lport_ns_sm_sending_gid_ft);
4343a36c61f9SKrishna Gudipati 			bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
4344a36c61f9SKrishna Gudipati 		};
4345a36c61f9SKrishna Gudipati 		break;
4346a36c61f9SKrishna Gudipati 
4347a36c61f9SKrishna Gudipati 	default:
4348a36c61f9SKrishna Gudipati 		bfa_sm_fault(ns->port->fcs, event);
4349a36c61f9SKrishna Gudipati 	}
4350a36c61f9SKrishna Gudipati }
4351a36c61f9SKrishna Gudipati 
4352a36c61f9SKrishna Gudipati 
4353a36c61f9SKrishna Gudipati 
43545fbe25c7SJing Huang /*
4355a36c61f9SKrishna Gudipati  *  ns_pvt Nameserver local functions
4356a36c61f9SKrishna Gudipati  */
4357a36c61f9SKrishna Gudipati 
4358a36c61f9SKrishna Gudipati static void
4359a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4360a36c61f9SKrishna Gudipati {
4361a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4362a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4363a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4364a36c61f9SKrishna Gudipati 	int             len;
4365a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4366a36c61f9SKrishna Gudipati 
4367a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
4368a36c61f9SKrishna Gudipati 
4369c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4370c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4371a36c61f9SKrishna Gudipati 	if (!fcxp) {
4372a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_alloc_wait++;
4373a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4374c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ns_send_plogi, ns, BFA_TRUE);
4375a36c61f9SKrishna Gudipati 		return;
4376a36c61f9SKrishna Gudipati 	}
4377a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
4378a36c61f9SKrishna Gudipati 
4379a36c61f9SKrishna Gudipati 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4380f16a1750SMaggie Zhang 			     bfa_hton3b(FC_NAME_SERVER),
4381a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port), 0,
4382a36c61f9SKrishna Gudipati 			     port->port_cfg.pwwn, port->port_cfg.nwwn,
4383be540a99SKrishna Gudipati 			     bfa_fcport_get_maxfrsize(port->fcs->bfa),
4384be540a99SKrishna Gudipati 			     bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
4385a36c61f9SKrishna Gudipati 
4386a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4387a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4388a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_plogi_response, (void *)ns,
4389a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_ELS_TOV);
4390a36c61f9SKrishna Gudipati 	port->stats.ns_plogi_sent++;
4391a36c61f9SKrishna Gudipati 
4392a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
4393a36c61f9SKrishna Gudipati }
4394a36c61f9SKrishna Gudipati 
4395a36c61f9SKrishna Gudipati static void
4396a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4397a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
4398a36c61f9SKrishna Gudipati 		       u32 resid_len, struct fchs_s *rsp_fchs)
4399a36c61f9SKrishna Gudipati {
4400a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4401a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4402a36c61f9SKrishna Gudipati 	/* struct fc_logi_s *plogi_resp; */
4403a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd;
4404a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
4405a36c61f9SKrishna Gudipati 
4406a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, req_status);
4407a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4408a36c61f9SKrishna Gudipati 
4409a36c61f9SKrishna Gudipati 	/*
4410a36c61f9SKrishna Gudipati 	 * Sanity Checks
4411a36c61f9SKrishna Gudipati 	 */
4412a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4413a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4414a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_rsp_err++;
4415a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4416a36c61f9SKrishna Gudipati 		return;
4417a36c61f9SKrishna Gudipati 	}
4418a36c61f9SKrishna Gudipati 
4419a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
4420a36c61f9SKrishna Gudipati 
4421a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
4422a36c61f9SKrishna Gudipati 
4423a36c61f9SKrishna Gudipati 	case FC_ELS_ACC:
4424a36c61f9SKrishna Gudipati 		if (rsp_len < sizeof(struct fc_logi_s)) {
4425a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rsp_len);
4426a36c61f9SKrishna Gudipati 			port->stats.ns_plogi_acc_err++;
4427a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4428a36c61f9SKrishna Gudipati 			break;
4429a36c61f9SKrishna Gudipati 		}
4430a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_accepts++;
4431a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4432a36c61f9SKrishna Gudipati 		break;
4433a36c61f9SKrishna Gudipati 
4434a36c61f9SKrishna Gudipati 	case FC_ELS_LS_RJT:
4435a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
4436a36c61f9SKrishna Gudipati 
4437a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code);
4438a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code_expl);
4439a36c61f9SKrishna Gudipati 
4440a36c61f9SKrishna Gudipati 		port->stats.ns_rejects++;
4441a36c61f9SKrishna Gudipati 
4442a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4443a36c61f9SKrishna Gudipati 		break;
4444a36c61f9SKrishna Gudipati 
4445a36c61f9SKrishna Gudipati 	default:
4446a36c61f9SKrishna Gudipati 		port->stats.ns_plogi_unknown_rsp++;
4447a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, els_cmd->els_code);
4448a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4449a36c61f9SKrishna Gudipati 	}
4450a36c61f9SKrishna Gudipati }
4451a36c61f9SKrishna Gudipati 
44525fbe25c7SJing Huang /*
4453ce7242b8SKrishna Gudipati  * Register node name for port_id
4454ce7242b8SKrishna Gudipati  */
4455ce7242b8SKrishna Gudipati static void
4456ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4457ce7242b8SKrishna Gudipati {
4458ce7242b8SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4459ce7242b8SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4460ce7242b8SKrishna Gudipati 	struct fchs_s  fchs;
4461ce7242b8SKrishna Gudipati 	int	len;
4462ce7242b8SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4463ce7242b8SKrishna Gudipati 
4464ce7242b8SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4465ce7242b8SKrishna Gudipati 
4466ce7242b8SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4467ce7242b8SKrishna Gudipati 			bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4468ce7242b8SKrishna Gudipati 	if (!fcxp) {
4469ce7242b8SKrishna Gudipati 		port->stats.ns_rnnid_alloc_wait++;
4470ce7242b8SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4471ce7242b8SKrishna Gudipati 				bfa_fcs_lport_ns_send_rnn_id, ns, BFA_TRUE);
4472ce7242b8SKrishna Gudipati 		return;
4473ce7242b8SKrishna Gudipati 	}
4474ce7242b8SKrishna Gudipati 
4475ce7242b8SKrishna Gudipati 	ns->fcxp = fcxp;
4476ce7242b8SKrishna Gudipati 
4477ce7242b8SKrishna Gudipati 	len = fc_rnnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4478ce7242b8SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port),
4479ce7242b8SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port),
4480ce7242b8SKrishna Gudipati 				bfa_fcs_lport_get_nwwn(port));
4481ce7242b8SKrishna Gudipati 
4482ce7242b8SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4483ce7242b8SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4484ce7242b8SKrishna Gudipati 			  bfa_fcs_lport_ns_rnn_id_response, (void *)ns,
4485ce7242b8SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
4486ce7242b8SKrishna Gudipati 
4487ce7242b8SKrishna Gudipati 	port->stats.ns_rnnid_sent++;
4488ce7242b8SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RNNID_SENT);
4489ce7242b8SKrishna Gudipati }
4490ce7242b8SKrishna Gudipati 
4491ce7242b8SKrishna Gudipati static void
4492ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_rnn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4493ce7242b8SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
4494ce7242b8SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
4495ce7242b8SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4496ce7242b8SKrishna Gudipati 
4497ce7242b8SKrishna Gudipati {
4498ce7242b8SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4499ce7242b8SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4500ce7242b8SKrishna Gudipati 	struct ct_hdr_s	*cthdr = NULL;
4501ce7242b8SKrishna Gudipati 
4502ce7242b8SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4503ce7242b8SKrishna Gudipati 
4504ce7242b8SKrishna Gudipati 	/*
4505ce7242b8SKrishna Gudipati 	 * Sanity Checks
4506ce7242b8SKrishna Gudipati 	 */
4507ce7242b8SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4508ce7242b8SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4509ce7242b8SKrishna Gudipati 		port->stats.ns_rnnid_rsp_err++;
4510ce7242b8SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4511ce7242b8SKrishna Gudipati 		return;
4512ce7242b8SKrishna Gudipati 	}
4513ce7242b8SKrishna Gudipati 
4514ce7242b8SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4515ce7242b8SKrishna Gudipati 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4516ce7242b8SKrishna Gudipati 
4517ce7242b8SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4518ce7242b8SKrishna Gudipati 		port->stats.ns_rnnid_accepts++;
4519ce7242b8SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4520ce7242b8SKrishna Gudipati 		return;
4521ce7242b8SKrishna Gudipati 	}
4522ce7242b8SKrishna Gudipati 
4523ce7242b8SKrishna Gudipati 	port->stats.ns_rnnid_rejects++;
4524ce7242b8SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
4525ce7242b8SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
4526ce7242b8SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4527ce7242b8SKrishna Gudipati }
4528ce7242b8SKrishna Gudipati 
4529ce7242b8SKrishna Gudipati /*
4530ce7242b8SKrishna Gudipati  * Register the symbolic node name for a given node name.
4531ce7242b8SKrishna Gudipati  */
4532ce7242b8SKrishna Gudipati static void
4533ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4534ce7242b8SKrishna Gudipati {
4535ce7242b8SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4536ce7242b8SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4537ce7242b8SKrishna Gudipati 	struct fchs_s  fchs;
4538ce7242b8SKrishna Gudipati 	int     len;
4539ce7242b8SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4540ce7242b8SKrishna Gudipati 	u8 *nsymbl;
4541ce7242b8SKrishna Gudipati 
4542ce7242b8SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4543ce7242b8SKrishna Gudipati 
4544ce7242b8SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4545ce7242b8SKrishna Gudipati 			bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4546ce7242b8SKrishna Gudipati 	if (!fcxp) {
4547ce7242b8SKrishna Gudipati 		port->stats.ns_rsnn_nn_alloc_wait++;
4548ce7242b8SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4549ce7242b8SKrishna Gudipati 				bfa_fcs_lport_ns_send_rsnn_nn, ns, BFA_TRUE);
4550ce7242b8SKrishna Gudipati 		return;
4551ce7242b8SKrishna Gudipati 	}
4552ce7242b8SKrishna Gudipati 	ns->fcxp = fcxp;
4553ce7242b8SKrishna Gudipati 
4554ce7242b8SKrishna Gudipati 	nsymbl = (u8 *) &(bfa_fcs_lport_get_nsym_name(
4555ce7242b8SKrishna Gudipati 					bfa_fcs_get_base_port(port->fcs)));
4556ce7242b8SKrishna Gudipati 
4557ce7242b8SKrishna Gudipati 	len = fc_rsnn_nn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4558ce7242b8SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port),
4559ce7242b8SKrishna Gudipati 				bfa_fcs_lport_get_nwwn(port), nsymbl);
4560ce7242b8SKrishna Gudipati 
4561ce7242b8SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4562ce7242b8SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4563ce7242b8SKrishna Gudipati 			  bfa_fcs_lport_ns_rsnn_nn_response, (void *)ns,
4564ce7242b8SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
4565ce7242b8SKrishna Gudipati 
4566ce7242b8SKrishna Gudipati 	port->stats.ns_rsnn_nn_sent++;
4567ce7242b8SKrishna Gudipati 
4568ce7242b8SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSNN_NN_SENT);
4569ce7242b8SKrishna Gudipati }
4570ce7242b8SKrishna Gudipati 
4571ce7242b8SKrishna Gudipati static void
4572ce7242b8SKrishna Gudipati bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4573ce7242b8SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
4574ce7242b8SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
4575ce7242b8SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4576ce7242b8SKrishna Gudipati {
4577ce7242b8SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4578ce7242b8SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4579ce7242b8SKrishna Gudipati 	struct ct_hdr_s	*cthdr = NULL;
4580ce7242b8SKrishna Gudipati 
4581ce7242b8SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4582ce7242b8SKrishna Gudipati 
4583ce7242b8SKrishna Gudipati 	/*
4584ce7242b8SKrishna Gudipati 	 * Sanity Checks
4585ce7242b8SKrishna Gudipati 	 */
4586ce7242b8SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4587ce7242b8SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4588ce7242b8SKrishna Gudipati 		port->stats.ns_rsnn_nn_rsp_err++;
4589ce7242b8SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4590ce7242b8SKrishna Gudipati 		return;
4591ce7242b8SKrishna Gudipati 	}
4592ce7242b8SKrishna Gudipati 
4593ce7242b8SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4594ce7242b8SKrishna Gudipati 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4595ce7242b8SKrishna Gudipati 
4596ce7242b8SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4597ce7242b8SKrishna Gudipati 		port->stats.ns_rsnn_nn_accepts++;
4598ce7242b8SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4599ce7242b8SKrishna Gudipati 		return;
4600ce7242b8SKrishna Gudipati 	}
4601ce7242b8SKrishna Gudipati 
4602ce7242b8SKrishna Gudipati 	port->stats.ns_rsnn_nn_rejects++;
4603ce7242b8SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
4604ce7242b8SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
4605ce7242b8SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4606ce7242b8SKrishna Gudipati }
4607ce7242b8SKrishna Gudipati 
4608ce7242b8SKrishna Gudipati /*
4609a36c61f9SKrishna Gudipati  * Register the symbolic port name.
4610a36c61f9SKrishna Gudipati  */
4611a36c61f9SKrishna Gudipati static void
4612a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4613a36c61f9SKrishna Gudipati {
4614a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4615a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4616a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4617a36c61f9SKrishna Gudipati 	int             len;
4618a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4619a36c61f9SKrishna Gudipati 	u8         symbl[256];
4620a36c61f9SKrishna Gudipati 	u8         *psymbl = &symbl[0];
4621a36c61f9SKrishna Gudipati 
46226a18b167SJing Huang 	memset(symbl, 0, sizeof(symbl));
4623a36c61f9SKrishna Gudipati 
4624a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4625a36c61f9SKrishna Gudipati 
4626c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4627c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4628a36c61f9SKrishna Gudipati 	if (!fcxp) {
4629a36c61f9SKrishna Gudipati 		port->stats.ns_rspnid_alloc_wait++;
4630a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4631c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ns_send_rspn_id, ns, BFA_TRUE);
4632a36c61f9SKrishna Gudipati 		return;
4633a36c61f9SKrishna Gudipati 	}
4634a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
4635a36c61f9SKrishna Gudipati 
4636a36c61f9SKrishna Gudipati 	/*
4637a36c61f9SKrishna Gudipati 	 * for V-Port, form a Port Symbolic Name
4638a36c61f9SKrishna Gudipati 	 */
4639a36c61f9SKrishna Gudipati 	if (port->vport) {
46405fbe25c7SJing Huang 		/*
4641a36c61f9SKrishna Gudipati 		 * For Vports, we append the vport's port symbolic name
4642a36c61f9SKrishna Gudipati 		 * to that of the base port.
4643a36c61f9SKrishna Gudipati 		 */
4644a36c61f9SKrishna Gudipati 
4645a36c61f9SKrishna Gudipati 		strncpy((char *)psymbl,
4646a36c61f9SKrishna Gudipati 			(char *) &
4647a36c61f9SKrishna Gudipati 			(bfa_fcs_lport_get_psym_name
4648a36c61f9SKrishna Gudipati 			 (bfa_fcs_get_base_port(port->fcs))),
4649a36c61f9SKrishna Gudipati 			strlen((char *) &
4650a36c61f9SKrishna Gudipati 			       bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
4651a36c61f9SKrishna Gudipati 							  (port->fcs))));
4652a36c61f9SKrishna Gudipati 
4653a36c61f9SKrishna Gudipati 		/* Ensure we have a null terminating string. */
4654a36c61f9SKrishna Gudipati 		((char *)psymbl)[strlen((char *) &
4655a36c61f9SKrishna Gudipati 			bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
4656a36c61f9SKrishna Gudipati 						(port->fcs)))] = 0;
4657a36c61f9SKrishna Gudipati 		strncat((char *)psymbl,
4658a36c61f9SKrishna Gudipati 			(char *) &(bfa_fcs_lport_get_psym_name(port)),
4659a36c61f9SKrishna Gudipati 		strlen((char *) &bfa_fcs_lport_get_psym_name(port)));
4660a36c61f9SKrishna Gudipati 	} else {
4661a36c61f9SKrishna Gudipati 		psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port));
4662a36c61f9SKrishna Gudipati 	}
4663a36c61f9SKrishna Gudipati 
4664a36c61f9SKrishna Gudipati 	len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4665a36c61f9SKrishna Gudipati 			      bfa_fcs_lport_get_fcid(port), 0, psymbl);
4666a36c61f9SKrishna Gudipati 
4667a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4668a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4669a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_rspn_id_response, (void *)ns,
4670a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
4671a36c61f9SKrishna Gudipati 
4672a36c61f9SKrishna Gudipati 	port->stats.ns_rspnid_sent++;
4673a36c61f9SKrishna Gudipati 
4674a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
4675a36c61f9SKrishna Gudipati }
4676a36c61f9SKrishna Gudipati 
4677a36c61f9SKrishna Gudipati static void
4678a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4679a36c61f9SKrishna Gudipati 				 void *cbarg, bfa_status_t req_status,
4680a36c61f9SKrishna Gudipati 				 u32 rsp_len, u32 resid_len,
4681a36c61f9SKrishna Gudipati 				 struct fchs_s *rsp_fchs)
4682a36c61f9SKrishna Gudipati {
4683a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4684a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4685a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
4686a36c61f9SKrishna Gudipati 
4687a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4688a36c61f9SKrishna Gudipati 
4689a36c61f9SKrishna Gudipati 	/*
4690a36c61f9SKrishna Gudipati 	 * Sanity Checks
4691a36c61f9SKrishna Gudipati 	 */
4692a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4693a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4694a36c61f9SKrishna Gudipati 		port->stats.ns_rspnid_rsp_err++;
4695a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4696a36c61f9SKrishna Gudipati 		return;
4697a36c61f9SKrishna Gudipati 	}
4698a36c61f9SKrishna Gudipati 
4699a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4700ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4701a36c61f9SKrishna Gudipati 
4702a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4703a36c61f9SKrishna Gudipati 		port->stats.ns_rspnid_accepts++;
4704a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4705a36c61f9SKrishna Gudipati 		return;
4706a36c61f9SKrishna Gudipati 	}
4707a36c61f9SKrishna Gudipati 
4708a36c61f9SKrishna Gudipati 	port->stats.ns_rspnid_rejects++;
4709a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
4710a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
4711a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4712a36c61f9SKrishna Gudipati }
4713a36c61f9SKrishna Gudipati 
47145fbe25c7SJing Huang /*
4715a36c61f9SKrishna Gudipati  * Register FC4-Types
4716a36c61f9SKrishna Gudipati  */
4717a36c61f9SKrishna Gudipati static void
4718a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4719a36c61f9SKrishna Gudipati {
4720a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4721a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4722a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4723a36c61f9SKrishna Gudipati 	int             len;
4724a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4725a36c61f9SKrishna Gudipati 
4726a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4727a36c61f9SKrishna Gudipati 
4728c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4729c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4730a36c61f9SKrishna Gudipati 	if (!fcxp) {
4731a36c61f9SKrishna Gudipati 		port->stats.ns_rftid_alloc_wait++;
4732a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4733c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ns_send_rft_id, ns, BFA_TRUE);
4734a36c61f9SKrishna Gudipati 		return;
4735a36c61f9SKrishna Gudipati 	}
4736a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
4737a36c61f9SKrishna Gudipati 
4738a36c61f9SKrishna Gudipati 	len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4739a36c61f9SKrishna Gudipati 		     bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles);
4740a36c61f9SKrishna Gudipati 
4741a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4742a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4743a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_rft_id_response, (void *)ns,
4744a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
4745a36c61f9SKrishna Gudipati 
4746a36c61f9SKrishna Gudipati 	port->stats.ns_rftid_sent++;
4747a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
4748a36c61f9SKrishna Gudipati }
4749a36c61f9SKrishna Gudipati 
4750a36c61f9SKrishna Gudipati static void
4751a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4752a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
4753a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
4754a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4755a36c61f9SKrishna Gudipati {
4756a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4757a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4758a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
4759a36c61f9SKrishna Gudipati 
4760a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4761a36c61f9SKrishna Gudipati 
4762a36c61f9SKrishna Gudipati 	/*
4763a36c61f9SKrishna Gudipati 	 * Sanity Checks
4764a36c61f9SKrishna Gudipati 	 */
4765a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4766a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4767a36c61f9SKrishna Gudipati 		port->stats.ns_rftid_rsp_err++;
4768a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4769a36c61f9SKrishna Gudipati 		return;
4770a36c61f9SKrishna Gudipati 	}
4771a36c61f9SKrishna Gudipati 
4772a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4773ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4774a36c61f9SKrishna Gudipati 
4775a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4776a36c61f9SKrishna Gudipati 		port->stats.ns_rftid_accepts++;
4777a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4778a36c61f9SKrishna Gudipati 		return;
4779a36c61f9SKrishna Gudipati 	}
4780a36c61f9SKrishna Gudipati 
4781a36c61f9SKrishna Gudipati 	port->stats.ns_rftid_rejects++;
4782a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
4783a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
4784a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4785a36c61f9SKrishna Gudipati }
4786a36c61f9SKrishna Gudipati 
47875fbe25c7SJing Huang /*
4788a36c61f9SKrishna Gudipati  * Register FC4-Features : Should be done after RFT_ID
4789a36c61f9SKrishna Gudipati  */
4790a36c61f9SKrishna Gudipati static void
4791a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4792a36c61f9SKrishna Gudipati {
4793a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4794a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4795a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4796a36c61f9SKrishna Gudipati 	int             len;
4797a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4798a36c61f9SKrishna Gudipati 	u8			fc4_ftrs = 0;
4799a36c61f9SKrishna Gudipati 
4800a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4801a36c61f9SKrishna Gudipati 
4802c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4803c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4804a36c61f9SKrishna Gudipati 	if (!fcxp) {
4805a36c61f9SKrishna Gudipati 		port->stats.ns_rffid_alloc_wait++;
4806a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4807c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ns_send_rff_id, ns, BFA_TRUE);
4808a36c61f9SKrishna Gudipati 		return;
4809a36c61f9SKrishna Gudipati 	}
4810a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
4811a36c61f9SKrishna Gudipati 
4812a36c61f9SKrishna Gudipati 	if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port))
4813a36c61f9SKrishna Gudipati 		fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
4814a36c61f9SKrishna Gudipati 
4815a36c61f9SKrishna Gudipati 	len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4816a36c61f9SKrishna Gudipati 			     bfa_fcs_lport_get_fcid(port), 0,
4817a36c61f9SKrishna Gudipati 				 FC_TYPE_FCP, fc4_ftrs);
4818a36c61f9SKrishna Gudipati 
4819a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4820a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4821a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_rff_id_response, (void *)ns,
4822a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, FC_FCCT_TOV);
4823a36c61f9SKrishna Gudipati 
4824a36c61f9SKrishna Gudipati 	port->stats.ns_rffid_sent++;
4825a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
4826a36c61f9SKrishna Gudipati }
4827a36c61f9SKrishna Gudipati 
4828a36c61f9SKrishna Gudipati static void
4829a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4830a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
4831a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
4832a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4833a36c61f9SKrishna Gudipati {
4834a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4835a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4836a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
4837a36c61f9SKrishna Gudipati 
4838a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4839a36c61f9SKrishna Gudipati 
4840a36c61f9SKrishna Gudipati 	/*
4841a36c61f9SKrishna Gudipati 	 * Sanity Checks
4842a36c61f9SKrishna Gudipati 	 */
4843a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4844a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4845a36c61f9SKrishna Gudipati 		port->stats.ns_rffid_rsp_err++;
4846a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4847a36c61f9SKrishna Gudipati 		return;
4848a36c61f9SKrishna Gudipati 	}
4849a36c61f9SKrishna Gudipati 
4850a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4851ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4852a36c61f9SKrishna Gudipati 
4853a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4854a36c61f9SKrishna Gudipati 		port->stats.ns_rffid_accepts++;
4855a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4856a36c61f9SKrishna Gudipati 		return;
4857a36c61f9SKrishna Gudipati 	}
4858a36c61f9SKrishna Gudipati 
4859a36c61f9SKrishna Gudipati 	port->stats.ns_rffid_rejects++;
4860a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->reason_code);
4861a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, cthdr->exp_code);
4862a36c61f9SKrishna Gudipati 
4863a36c61f9SKrishna Gudipati 	if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
4864a36c61f9SKrishna Gudipati 		/* if this command is not supported, we don't retry */
4865a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4866a36c61f9SKrishna Gudipati 	} else
4867a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4868a36c61f9SKrishna Gudipati }
48695fbe25c7SJing Huang /*
4870a36c61f9SKrishna Gudipati  * Query Fabric for FC4-Types Devices.
4871a36c61f9SKrishna Gudipati  *
4872a36c61f9SKrishna Gudipati * TBD : Need to use a local (FCS private) response buffer, since the response
4873a36c61f9SKrishna Gudipati  * can be larger than 2K.
4874a36c61f9SKrishna Gudipati  */
4875a36c61f9SKrishna Gudipati static void
4876a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4877a36c61f9SKrishna Gudipati {
4878a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4879a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4880a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
4881a36c61f9SKrishna Gudipati 	int             len;
4882a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
4883a36c61f9SKrishna Gudipati 
4884a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
4885a36c61f9SKrishna Gudipati 
4886c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
4887c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4888a36c61f9SKrishna Gudipati 	if (!fcxp) {
4889a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_alloc_wait++;
4890a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4891c3f1b123SKrishna Gudipati 				bfa_fcs_lport_ns_send_gid_ft, ns, BFA_TRUE);
4892a36c61f9SKrishna Gudipati 		return;
4893a36c61f9SKrishna Gudipati 	}
4894a36c61f9SKrishna Gudipati 	ns->fcxp = fcxp;
4895a36c61f9SKrishna Gudipati 
4896a36c61f9SKrishna Gudipati 	/*
4897a36c61f9SKrishna Gudipati 	 * This query is only initiated for FCP initiator mode.
4898a36c61f9SKrishna Gudipati 	 */
4899a36c61f9SKrishna Gudipati 	len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4900a36c61f9SKrishna Gudipati 			      ns->port->pid, FC_TYPE_FCP);
4901a36c61f9SKrishna Gudipati 
4902a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4903a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
4904a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_ns_gid_ft_response, (void *)ns,
4905a36c61f9SKrishna Gudipati 			  bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV);
4906a36c61f9SKrishna Gudipati 
4907a36c61f9SKrishna Gudipati 	port->stats.ns_gidft_sent++;
4908a36c61f9SKrishna Gudipati 
4909a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
4910a36c61f9SKrishna Gudipati }
4911a36c61f9SKrishna Gudipati 
4912a36c61f9SKrishna Gudipati static void
4913a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4914a36c61f9SKrishna Gudipati 				void *cbarg, bfa_status_t req_status,
4915a36c61f9SKrishna Gudipati 				u32 rsp_len, u32 resid_len,
4916a36c61f9SKrishna Gudipati 				struct fchs_s *rsp_fchs)
4917a36c61f9SKrishna Gudipati {
4918a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4919a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
4920a36c61f9SKrishna Gudipati 	struct ct_hdr_s *cthdr = NULL;
4921a36c61f9SKrishna Gudipati 	u32        n_pids;
4922a36c61f9SKrishna Gudipati 
4923a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
4924a36c61f9SKrishna Gudipati 
4925a36c61f9SKrishna Gudipati 	/*
4926a36c61f9SKrishna Gudipati 	 * Sanity Checks
4927a36c61f9SKrishna Gudipati 	 */
4928a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
4929a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
4930a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_rsp_err++;
4931a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4932a36c61f9SKrishna Gudipati 		return;
4933a36c61f9SKrishna Gudipati 	}
4934a36c61f9SKrishna Gudipati 
4935a36c61f9SKrishna Gudipati 	if (resid_len != 0) {
4936a36c61f9SKrishna Gudipati 		/*
4937a36c61f9SKrishna Gudipati 		 * TBD : we will need to allocate a larger buffer & retry the
4938a36c61f9SKrishna Gudipati 		 * command
4939a36c61f9SKrishna Gudipati 		 */
4940a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rsp_len);
4941a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, resid_len);
4942a36c61f9SKrishna Gudipati 		return;
4943a36c61f9SKrishna Gudipati 	}
4944a36c61f9SKrishna Gudipati 
4945a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4946ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4947a36c61f9SKrishna Gudipati 
4948a36c61f9SKrishna Gudipati 	switch (cthdr->cmd_rsp_code) {
4949a36c61f9SKrishna Gudipati 
4950a36c61f9SKrishna Gudipati 	case CT_RSP_ACCEPT:
4951a36c61f9SKrishna Gudipati 
4952a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_accepts++;
4953a36c61f9SKrishna Gudipati 		n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
4954a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, n_pids);
4955a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_process_gidft_pids(port,
4956a36c61f9SKrishna Gudipati 						   (u32 *) (cthdr + 1),
4957a36c61f9SKrishna Gudipati 						   n_pids);
4958a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4959a36c61f9SKrishna Gudipati 		break;
4960a36c61f9SKrishna Gudipati 
4961a36c61f9SKrishna Gudipati 	case CT_RSP_REJECT:
4962a36c61f9SKrishna Gudipati 
4963a36c61f9SKrishna Gudipati 		/*
4964a36c61f9SKrishna Gudipati 		 * Check the reason code  & explanation.
4965a36c61f9SKrishna Gudipati 		 * There may not have been any FC4 devices in the fabric
4966a36c61f9SKrishna Gudipati 		 */
4967a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_rejects++;
4968a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, cthdr->reason_code);
4969a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, cthdr->exp_code);
4970a36c61f9SKrishna Gudipati 
4971a36c61f9SKrishna Gudipati 		if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
4972a36c61f9SKrishna Gudipati 		    && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
4973a36c61f9SKrishna Gudipati 
4974a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4975a36c61f9SKrishna Gudipati 		} else {
4976a36c61f9SKrishna Gudipati 			/*
4977a36c61f9SKrishna Gudipati 			 * for all other errors, retry
4978a36c61f9SKrishna Gudipati 			 */
4979a36c61f9SKrishna Gudipati 			bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4980a36c61f9SKrishna Gudipati 		}
4981a36c61f9SKrishna Gudipati 		break;
4982a36c61f9SKrishna Gudipati 
4983a36c61f9SKrishna Gudipati 	default:
4984a36c61f9SKrishna Gudipati 		port->stats.ns_gidft_unknown_rsp++;
4985a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, cthdr->cmd_rsp_code);
4986a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4987a36c61f9SKrishna Gudipati 	}
4988a36c61f9SKrishna Gudipati }
4989a36c61f9SKrishna Gudipati 
49905fbe25c7SJing Huang /*
4991a36c61f9SKrishna Gudipati  *     This routine will be called by bfa_timer on timer timeouts.
4992a36c61f9SKrishna Gudipati  *
4993a36c61f9SKrishna Gudipati  *	param[in]	port - pointer to bfa_fcs_lport_t.
4994a36c61f9SKrishna Gudipati  *
4995a36c61f9SKrishna Gudipati  *	return
4996a36c61f9SKrishna Gudipati  *		void
4997a36c61f9SKrishna Gudipati  *
4998a36c61f9SKrishna Gudipati  *	Special Considerations:
4999a36c61f9SKrishna Gudipati  *
5000a36c61f9SKrishna Gudipati  *	note
5001a36c61f9SKrishna Gudipati  */
5002a36c61f9SKrishna Gudipati static void
5003a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_timeout(void *arg)
5004a36c61f9SKrishna Gudipati {
5005a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg;
5006a36c61f9SKrishna Gudipati 
5007a36c61f9SKrishna Gudipati 	ns->port->stats.ns_timeouts++;
5008a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
5009a36c61f9SKrishna Gudipati }
5010a36c61f9SKrishna Gudipati 
5011a36c61f9SKrishna Gudipati /*
5012a36c61f9SKrishna Gudipati  * Process the PID list in GID_FT response
5013a36c61f9SKrishna Gudipati  */
5014a36c61f9SKrishna Gudipati static void
5015a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf,
5016a36c61f9SKrishna Gudipati 				   u32 n_pids)
5017a36c61f9SKrishna Gudipati {
5018a36c61f9SKrishna Gudipati 	struct fcgs_gidft_resp_s *gidft_entry;
5019a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
5020a36c61f9SKrishna Gudipati 	u32        ii;
502161ba4394SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = port->fabric;
502261ba4394SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
502361ba4394SKrishna Gudipati 	struct list_head *qe;
502461ba4394SKrishna Gudipati 	u8 found = 0;
5025a36c61f9SKrishna Gudipati 
5026a36c61f9SKrishna Gudipati 	for (ii = 0; ii < n_pids; ii++) {
5027a36c61f9SKrishna Gudipati 		gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
5028a36c61f9SKrishna Gudipati 
5029a36c61f9SKrishna Gudipati 		if (gidft_entry->pid == port->pid)
5030a36c61f9SKrishna Gudipati 			continue;
5031a36c61f9SKrishna Gudipati 
5032a36c61f9SKrishna Gudipati 		/*
503361ba4394SKrishna Gudipati 		 * Ignore PID if it is of base port
503461ba4394SKrishna Gudipati 		 * (Avoid vports discovering base port as remote port)
503561ba4394SKrishna Gudipati 		 */
503661ba4394SKrishna Gudipati 		if (gidft_entry->pid == fabric->bport.pid)
503761ba4394SKrishna Gudipati 			continue;
503861ba4394SKrishna Gudipati 
503961ba4394SKrishna Gudipati 		/*
504061ba4394SKrishna Gudipati 		 * Ignore PID if it is of vport created on the same base port
504161ba4394SKrishna Gudipati 		 * (Avoid vport discovering every other vport created on the
504261ba4394SKrishna Gudipati 		 * same port as remote port)
504361ba4394SKrishna Gudipati 		 */
504461ba4394SKrishna Gudipati 		list_for_each(qe, &fabric->vport_q) {
504561ba4394SKrishna Gudipati 			vport = (struct bfa_fcs_vport_s *) qe;
504661ba4394SKrishna Gudipati 			if (vport->lport.pid == gidft_entry->pid)
504761ba4394SKrishna Gudipati 				found = 1;
504861ba4394SKrishna Gudipati 		}
504961ba4394SKrishna Gudipati 
505061ba4394SKrishna Gudipati 		if (found) {
505161ba4394SKrishna Gudipati 			found = 0;
505261ba4394SKrishna Gudipati 			continue;
505361ba4394SKrishna Gudipati 		}
505461ba4394SKrishna Gudipati 
505561ba4394SKrishna Gudipati 		/*
5056a36c61f9SKrishna Gudipati 		 * Check if this rport already exists
5057a36c61f9SKrishna Gudipati 		 */
5058a36c61f9SKrishna Gudipati 		rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid);
5059a36c61f9SKrishna Gudipati 		if (rport == NULL) {
5060a36c61f9SKrishna Gudipati 			/*
5061a36c61f9SKrishna Gudipati 			 * this is a new device. create rport
5062a36c61f9SKrishna Gudipati 			 */
5063a36c61f9SKrishna Gudipati 			rport = bfa_fcs_rport_create(port, gidft_entry->pid);
5064a36c61f9SKrishna Gudipati 		} else {
5065a36c61f9SKrishna Gudipati 			/*
5066a36c61f9SKrishna Gudipati 			 * this rport already exists
5067a36c61f9SKrishna Gudipati 			 */
5068a36c61f9SKrishna Gudipati 			bfa_fcs_rport_scn(rport);
5069a36c61f9SKrishna Gudipati 		}
5070a36c61f9SKrishna Gudipati 
5071a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, gidft_entry->pid);
5072a36c61f9SKrishna Gudipati 
5073a36c61f9SKrishna Gudipati 		/*
5074a36c61f9SKrishna Gudipati 		 * if the last entry bit is set, bail out.
5075a36c61f9SKrishna Gudipati 		 */
5076a36c61f9SKrishna Gudipati 		if (gidft_entry->last)
5077a36c61f9SKrishna Gudipati 			return;
5078a36c61f9SKrishna Gudipati 	}
5079a36c61f9SKrishna Gudipati }
5080a36c61f9SKrishna Gudipati 
50815fbe25c7SJing Huang /*
5082a36c61f9SKrishna Gudipati  *  fcs_ns_public FCS nameserver public interfaces
5083a36c61f9SKrishna Gudipati  */
5084a36c61f9SKrishna Gudipati 
5085a36c61f9SKrishna Gudipati /*
5086a36c61f9SKrishna Gudipati  * Functions called by port/fab.
5087a36c61f9SKrishna Gudipati  * These will send relevant Events to the ns state machine.
5088a36c61f9SKrishna Gudipati  */
5089a36c61f9SKrishna Gudipati void
5090a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port)
5091a36c61f9SKrishna Gudipati {
5092a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
5093a36c61f9SKrishna Gudipati 
5094a36c61f9SKrishna Gudipati 	ns->port = port;
5095a36c61f9SKrishna Gudipati 	bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
5096a36c61f9SKrishna Gudipati }
5097a36c61f9SKrishna Gudipati 
5098a36c61f9SKrishna Gudipati void
5099a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port)
5100a36c61f9SKrishna Gudipati {
5101a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
5102a36c61f9SKrishna Gudipati 
5103a36c61f9SKrishna Gudipati 	ns->port = port;
5104a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
5105a36c61f9SKrishna Gudipati }
5106a36c61f9SKrishna Gudipati 
5107a36c61f9SKrishna Gudipati void
5108a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port)
5109a36c61f9SKrishna Gudipati {
5110a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
5111a36c61f9SKrishna Gudipati 
5112a36c61f9SKrishna Gudipati 	ns->port = port;
5113a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
5114a36c61f9SKrishna Gudipati }
5115a36c61f9SKrishna Gudipati 
5116a36c61f9SKrishna Gudipati void
5117a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port)
5118a36c61f9SKrishna Gudipati {
5119a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
5120a36c61f9SKrishna Gudipati 
5121a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
512261ba4394SKrishna Gudipati 	if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_online))
5123a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
5124a36c61f9SKrishna Gudipati }
5125a36c61f9SKrishna Gudipati 
512652f94b6fSMaggie static void
5127a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
5128a36c61f9SKrishna Gudipati {
5129a36c61f9SKrishna Gudipati 
5130a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
5131a36c61f9SKrishna Gudipati 	u8 nwwns;
5132a36c61f9SKrishna Gudipati 	wwn_t  wwns[BFA_PREBOOT_BOOTLUN_MAX];
5133a36c61f9SKrishna Gudipati 	int ii;
5134a36c61f9SKrishna Gudipati 
5135a36c61f9SKrishna Gudipati 	bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns);
5136a36c61f9SKrishna Gudipati 
5137a36c61f9SKrishna Gudipati 	for (ii = 0 ; ii < nwwns; ++ii) {
5138a36c61f9SKrishna Gudipati 		rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
5139d4b671c5SJing Huang 		WARN_ON(!rport);
5140a36c61f9SKrishna Gudipati 	}
5141a36c61f9SKrishna Gudipati }
5142a36c61f9SKrishna Gudipati 
5143ebfe8392SKrishna Gudipati void
5144ebfe8392SKrishna Gudipati bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced)
5145ebfe8392SKrishna Gudipati {
5146ebfe8392SKrishna Gudipati 	struct bfa_fcs_lport_ns_s *ns = cbarg;
5147ebfe8392SKrishna Gudipati 	struct bfa_fcs_lport_s *port = ns->port;
5148ebfe8392SKrishna Gudipati 	struct fchs_s fchs;
5149ebfe8392SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
5150ebfe8392SKrishna Gudipati 	u8 symbl[256];
5151ebfe8392SKrishna Gudipati 	u8 *psymbl = &symbl[0];
5152ebfe8392SKrishna Gudipati 	int len;
5153ebfe8392SKrishna Gudipati 
5154ebfe8392SKrishna Gudipati 	/* Avoid sending RSPN in the following states. */
5155ebfe8392SKrishna Gudipati 	if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) ||
5156ebfe8392SKrishna Gudipati 	    bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) ||
5157ebfe8392SKrishna Gudipati 	    bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi) ||
5158ebfe8392SKrishna Gudipati 	    bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_retry) ||
5159ebfe8392SKrishna Gudipati 	    bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry))
5160ebfe8392SKrishna Gudipati 		return;
5161ebfe8392SKrishna Gudipati 
5162ebfe8392SKrishna Gudipati 	memset(symbl, 0, sizeof(symbl));
5163ebfe8392SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
5164ebfe8392SKrishna Gudipati 
5165c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
5166c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
5167ebfe8392SKrishna Gudipati 	if (!fcxp) {
5168ebfe8392SKrishna Gudipati 		port->stats.ns_rspnid_alloc_wait++;
5169ebfe8392SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
5170c3f1b123SKrishna Gudipati 			bfa_fcs_lport_ns_util_send_rspn_id, ns, BFA_FALSE);
5171ebfe8392SKrishna Gudipati 		return;
5172ebfe8392SKrishna Gudipati 	}
5173ebfe8392SKrishna Gudipati 
5174ebfe8392SKrishna Gudipati 	ns->fcxp = fcxp;
5175ebfe8392SKrishna Gudipati 
5176ebfe8392SKrishna Gudipati 	if (port->vport) {
5177ebfe8392SKrishna Gudipati 		/*
5178ebfe8392SKrishna Gudipati 		 * For Vports, we append the vport's port symbolic name
5179ebfe8392SKrishna Gudipati 		 * to that of the base port.
5180ebfe8392SKrishna Gudipati 		 */
5181ebfe8392SKrishna Gudipati 		strncpy((char *)psymbl, (char *)&(bfa_fcs_lport_get_psym_name
5182ebfe8392SKrishna Gudipati 			(bfa_fcs_get_base_port(port->fcs))),
5183ebfe8392SKrishna Gudipati 			strlen((char *)&bfa_fcs_lport_get_psym_name(
5184ebfe8392SKrishna Gudipati 			bfa_fcs_get_base_port(port->fcs))));
5185ebfe8392SKrishna Gudipati 
5186ebfe8392SKrishna Gudipati 		/* Ensure we have a null terminating string. */
5187ebfe8392SKrishna Gudipati 		((char *)psymbl)[strlen((char *)&bfa_fcs_lport_get_psym_name(
5188ebfe8392SKrishna Gudipati 		 bfa_fcs_get_base_port(port->fcs)))] = 0;
5189ebfe8392SKrishna Gudipati 
5190ebfe8392SKrishna Gudipati 		strncat((char *)psymbl,
5191ebfe8392SKrishna Gudipati 			(char *)&(bfa_fcs_lport_get_psym_name(port)),
5192ebfe8392SKrishna Gudipati 			strlen((char *)&bfa_fcs_lport_get_psym_name(port)));
5193ebfe8392SKrishna Gudipati 	}
5194ebfe8392SKrishna Gudipati 
5195ebfe8392SKrishna Gudipati 	len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5196ebfe8392SKrishna Gudipati 			      bfa_fcs_lport_get_fcid(port), 0, psymbl);
5197ebfe8392SKrishna Gudipati 
5198ebfe8392SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
5199ebfe8392SKrishna Gudipati 		      FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
5200ebfe8392SKrishna Gudipati 
5201ebfe8392SKrishna Gudipati 	port->stats.ns_rspnid_sent++;
5202ebfe8392SKrishna Gudipati }
5203ebfe8392SKrishna Gudipati 
52045fbe25c7SJing Huang /*
5205a36c61f9SKrishna Gudipati  * FCS SCN
5206a36c61f9SKrishna Gudipati  */
5207a36c61f9SKrishna Gudipati 
5208a36c61f9SKrishna Gudipati #define FC_QOS_RSCN_EVENT		0x0c
5209a36c61f9SKrishna Gudipati #define FC_FABRIC_NAME_RSCN_EVENT	0x0d
5210a36c61f9SKrishna Gudipati 
5211a36c61f9SKrishna Gudipati /*
5212a36c61f9SKrishna Gudipati  * forward declarations
5213a36c61f9SKrishna Gudipati  */
5214a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_send_scr(void *scn_cbarg,
5215a36c61f9SKrishna Gudipati 					  struct bfa_fcxp_s *fcxp_alloced);
5216a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_scr_response(void *fcsarg,
5217a36c61f9SKrishna Gudipati 					      struct bfa_fcxp_s *fcxp,
5218a36c61f9SKrishna Gudipati 					      void *cbarg,
5219a36c61f9SKrishna Gudipati 					      bfa_status_t req_status,
5220a36c61f9SKrishna Gudipati 					      u32 rsp_len,
5221a36c61f9SKrishna Gudipati 					      u32 resid_len,
5222a36c61f9SKrishna Gudipati 					      struct fchs_s *rsp_fchs);
5223a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
5224a36c61f9SKrishna Gudipati 					     struct fchs_s *rx_fchs);
5225a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_timeout(void *arg);
5226a36c61f9SKrishna Gudipati 
52275fbe25c7SJing Huang /*
5228a36c61f9SKrishna Gudipati  *  fcs_scm_sm FCS SCN state machine
5229a36c61f9SKrishna Gudipati  */
5230a36c61f9SKrishna Gudipati 
52315fbe25c7SJing Huang /*
5232a36c61f9SKrishna Gudipati  * VPort SCN State Machine events
5233a36c61f9SKrishna Gudipati  */
5234a36c61f9SKrishna Gudipati enum port_scn_event {
5235a36c61f9SKrishna Gudipati 	SCNSM_EVENT_PORT_ONLINE = 1,
5236a36c61f9SKrishna Gudipati 	SCNSM_EVENT_PORT_OFFLINE = 2,
5237a36c61f9SKrishna Gudipati 	SCNSM_EVENT_RSP_OK = 3,
5238a36c61f9SKrishna Gudipati 	SCNSM_EVENT_RSP_ERROR = 4,
5239a36c61f9SKrishna Gudipati 	SCNSM_EVENT_TIMEOUT = 5,
5240a36c61f9SKrishna Gudipati 	SCNSM_EVENT_SCR_SENT = 6,
5241a36c61f9SKrishna Gudipati };
5242a36c61f9SKrishna Gudipati 
5243a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
5244a36c61f9SKrishna Gudipati 					    enum port_scn_event event);
5245a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_sending_scr(
5246a36c61f9SKrishna Gudipati 					struct bfa_fcs_lport_scn_s *scn,
5247a36c61f9SKrishna Gudipati 					enum port_scn_event event);
5248a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
5249a36c61f9SKrishna Gudipati 					enum port_scn_event event);
5250a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
5251a36c61f9SKrishna Gudipati 					      enum port_scn_event event);
5252a36c61f9SKrishna Gudipati static void     bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
5253a36c61f9SKrishna Gudipati 					   enum port_scn_event event);
5254a36c61f9SKrishna Gudipati 
52555fbe25c7SJing Huang /*
5256a36c61f9SKrishna Gudipati  *	Starting state - awaiting link up.
5257a36c61f9SKrishna Gudipati  */
5258a36c61f9SKrishna Gudipati static void
5259a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
5260a36c61f9SKrishna Gudipati 			enum port_scn_event event)
5261a36c61f9SKrishna Gudipati {
5262a36c61f9SKrishna Gudipati 	switch (event) {
5263a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_ONLINE:
5264a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
5265a36c61f9SKrishna Gudipati 		bfa_fcs_lport_scn_send_scr(scn, NULL);
5266a36c61f9SKrishna Gudipati 		break;
5267a36c61f9SKrishna Gudipati 
5268a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
5269a36c61f9SKrishna Gudipati 		break;
5270a36c61f9SKrishna Gudipati 
5271a36c61f9SKrishna Gudipati 	default:
5272a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
5273a36c61f9SKrishna Gudipati 	}
5274a36c61f9SKrishna Gudipati }
5275a36c61f9SKrishna Gudipati 
5276a36c61f9SKrishna Gudipati static void
5277a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn,
5278a36c61f9SKrishna Gudipati 				enum port_scn_event event)
5279a36c61f9SKrishna Gudipati {
5280a36c61f9SKrishna Gudipati 	switch (event) {
5281a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_SCR_SENT:
5282a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr);
5283a36c61f9SKrishna Gudipati 		break;
5284a36c61f9SKrishna Gudipati 
5285a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
5286a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5287a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe);
5288a36c61f9SKrishna Gudipati 		break;
5289a36c61f9SKrishna Gudipati 
5290a36c61f9SKrishna Gudipati 	default:
5291a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
5292a36c61f9SKrishna Gudipati 	}
5293a36c61f9SKrishna Gudipati }
5294a36c61f9SKrishna Gudipati 
5295a36c61f9SKrishna Gudipati static void
5296a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
5297a36c61f9SKrishna Gudipati 			enum port_scn_event event)
5298a36c61f9SKrishna Gudipati {
5299a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = scn->port;
5300a36c61f9SKrishna Gudipati 
5301a36c61f9SKrishna Gudipati 	switch (event) {
5302a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_RSP_OK:
5303a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online);
5304a36c61f9SKrishna Gudipati 		break;
5305a36c61f9SKrishna Gudipati 
5306a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_RSP_ERROR:
5307a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry);
5308a36c61f9SKrishna Gudipati 		bfa_timer_start(port->fcs->bfa, &scn->timer,
5309a36c61f9SKrishna Gudipati 				    bfa_fcs_lport_scn_timeout, scn,
5310a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
5311a36c61f9SKrishna Gudipati 		break;
5312a36c61f9SKrishna Gudipati 
5313a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
5314a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5315a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(scn->fcxp);
5316a36c61f9SKrishna Gudipati 		break;
5317a36c61f9SKrishna Gudipati 
5318a36c61f9SKrishna Gudipati 	default:
5319a36c61f9SKrishna Gudipati 		bfa_sm_fault(port->fcs, event);
5320a36c61f9SKrishna Gudipati 	}
5321a36c61f9SKrishna Gudipati }
5322a36c61f9SKrishna Gudipati 
5323a36c61f9SKrishna Gudipati static void
5324a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
5325a36c61f9SKrishna Gudipati 				enum port_scn_event event)
5326a36c61f9SKrishna Gudipati {
5327a36c61f9SKrishna Gudipati 	switch (event) {
5328a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_TIMEOUT:
5329a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
5330a36c61f9SKrishna Gudipati 		bfa_fcs_lport_scn_send_scr(scn, NULL);
5331a36c61f9SKrishna Gudipati 		break;
5332a36c61f9SKrishna Gudipati 
5333a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
5334a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5335a36c61f9SKrishna Gudipati 		bfa_timer_stop(&scn->timer);
5336a36c61f9SKrishna Gudipati 		break;
5337a36c61f9SKrishna Gudipati 
5338a36c61f9SKrishna Gudipati 	default:
5339a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
5340a36c61f9SKrishna Gudipati 	}
5341a36c61f9SKrishna Gudipati }
5342a36c61f9SKrishna Gudipati 
5343a36c61f9SKrishna Gudipati static void
5344a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
5345a36c61f9SKrishna Gudipati 			enum port_scn_event event)
5346a36c61f9SKrishna Gudipati {
5347a36c61f9SKrishna Gudipati 	switch (event) {
5348a36c61f9SKrishna Gudipati 	case SCNSM_EVENT_PORT_OFFLINE:
5349a36c61f9SKrishna Gudipati 		bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5350a36c61f9SKrishna Gudipati 		break;
5351a36c61f9SKrishna Gudipati 
5352a36c61f9SKrishna Gudipati 	default:
5353a36c61f9SKrishna Gudipati 		bfa_sm_fault(scn->port->fcs, event);
5354a36c61f9SKrishna Gudipati 	}
5355a36c61f9SKrishna Gudipati }
5356a36c61f9SKrishna Gudipati 
5357a36c61f9SKrishna Gudipati 
5358a36c61f9SKrishna Gudipati 
53595fbe25c7SJing Huang /*
5360a36c61f9SKrishna Gudipati  *  fcs_scn_private FCS SCN private functions
5361a36c61f9SKrishna Gudipati  */
5362a36c61f9SKrishna Gudipati 
53635fbe25c7SJing Huang /*
5364a36c61f9SKrishna Gudipati  * This routine will be called to send a SCR command.
5365a36c61f9SKrishna Gudipati  */
5366a36c61f9SKrishna Gudipati static void
5367a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
5368a36c61f9SKrishna Gudipati {
5369a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = scn_cbarg;
5370a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = scn->port;
5371a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
5372a36c61f9SKrishna Gudipati 	int             len;
5373a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
5374a36c61f9SKrishna Gudipati 
5375a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->pid);
5376a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
5377a36c61f9SKrishna Gudipati 
5378c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
5379c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
5380a36c61f9SKrishna Gudipati 	if (!fcxp) {
5381a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
5382c3f1b123SKrishna Gudipati 				bfa_fcs_lport_scn_send_scr, scn, BFA_TRUE);
5383a36c61f9SKrishna Gudipati 		return;
5384a36c61f9SKrishna Gudipati 	}
5385a36c61f9SKrishna Gudipati 	scn->fcxp = fcxp;
5386a36c61f9SKrishna Gudipati 
5387a36c61f9SKrishna Gudipati 	/* Handle VU registrations for Base port only */
5388a36c61f9SKrishna Gudipati 	if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
5389a36c61f9SKrishna Gudipati 		len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5390f7f73812SMaggie Zhang 				port->fabric->lps->brcd_switch,
5391a36c61f9SKrishna Gudipati 				port->pid, 0);
5392a36c61f9SKrishna Gudipati 	} else {
5393a36c61f9SKrishna Gudipati 	    len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5394a36c61f9SKrishna Gudipati 				    BFA_FALSE,
5395a36c61f9SKrishna Gudipati 				    port->pid, 0);
5396a36c61f9SKrishna Gudipati 	}
5397a36c61f9SKrishna Gudipati 
5398a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
5399a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs,
5400a36c61f9SKrishna Gudipati 			  bfa_fcs_lport_scn_scr_response,
5401a36c61f9SKrishna Gudipati 			  (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV);
5402a36c61f9SKrishna Gudipati 
5403a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT);
5404a36c61f9SKrishna Gudipati }
5405a36c61f9SKrishna Gudipati 
5406a36c61f9SKrishna Gudipati static void
5407a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
5408a36c61f9SKrishna Gudipati 			void *cbarg, bfa_status_t req_status, u32 rsp_len,
5409a36c61f9SKrishna Gudipati 			      u32 resid_len, struct fchs_s *rsp_fchs)
5410a36c61f9SKrishna Gudipati {
5411a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg;
5412a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = scn->port;
5413a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd;
5414a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
5415a36c61f9SKrishna Gudipati 
5416a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->port_cfg.pwwn);
5417a36c61f9SKrishna Gudipati 
5418a36c61f9SKrishna Gudipati 	/*
5419a36c61f9SKrishna Gudipati 	 * Sanity Checks
5420a36c61f9SKrishna Gudipati 	 */
5421a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
5422a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, req_status);
5423a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
5424a36c61f9SKrishna Gudipati 		return;
5425a36c61f9SKrishna Gudipati 	}
5426a36c61f9SKrishna Gudipati 
5427a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
5428a36c61f9SKrishna Gudipati 
5429a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
5430a36c61f9SKrishna Gudipati 
5431a36c61f9SKrishna Gudipati 	case FC_ELS_ACC:
5432a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK);
5433a36c61f9SKrishna Gudipati 		break;
5434a36c61f9SKrishna Gudipati 
5435a36c61f9SKrishna Gudipati 	case FC_ELS_LS_RJT:
5436a36c61f9SKrishna Gudipati 
5437a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
5438a36c61f9SKrishna Gudipati 
5439a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code);
5440a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, ls_rjt->reason_code_expl);
5441a36c61f9SKrishna Gudipati 
5442a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
5443a36c61f9SKrishna Gudipati 		break;
5444a36c61f9SKrishna Gudipati 
5445a36c61f9SKrishna Gudipati 	default:
5446a36c61f9SKrishna Gudipati 		bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
5447a36c61f9SKrishna Gudipati 	}
5448a36c61f9SKrishna Gudipati }
5449a36c61f9SKrishna Gudipati 
5450a36c61f9SKrishna Gudipati /*
5451a36c61f9SKrishna Gudipati  * Send a LS Accept
5452a36c61f9SKrishna Gudipati  */
5453a36c61f9SKrishna Gudipati static void
5454a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
5455a36c61f9SKrishna Gudipati 				struct fchs_s *rx_fchs)
5456a36c61f9SKrishna Gudipati {
5457a36c61f9SKrishna Gudipati 	struct fchs_s fchs;
5458a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
5459a36c61f9SKrishna Gudipati 	struct bfa_rport_s *bfa_rport = NULL;
5460a36c61f9SKrishna Gudipati 	int             len;
5461a36c61f9SKrishna Gudipati 
5462a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
5463a36c61f9SKrishna Gudipati 
5464c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
5465a36c61f9SKrishna Gudipati 	if (!fcxp)
5466a36c61f9SKrishna Gudipati 		return;
5467a36c61f9SKrishna Gudipati 
5468a36c61f9SKrishna Gudipati 	len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5469a36c61f9SKrishna Gudipati 			      rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
5470a36c61f9SKrishna Gudipati 			      rx_fchs->ox_id);
5471a36c61f9SKrishna Gudipati 
5472a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
5473a36c61f9SKrishna Gudipati 			  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
5474a36c61f9SKrishna Gudipati 			  FC_MAX_PDUSZ, 0);
5475a36c61f9SKrishna Gudipati }
5476a36c61f9SKrishna Gudipati 
54775fbe25c7SJing Huang /*
5478a36c61f9SKrishna Gudipati  *     This routine will be called by bfa_timer on timer timeouts.
5479a36c61f9SKrishna Gudipati  *
5480a36c61f9SKrishna Gudipati  *	param[in]	vport		- pointer to bfa_fcs_lport_t.
5481a36c61f9SKrishna Gudipati  *	param[out]	vport_status	- pointer to return vport status in
5482a36c61f9SKrishna Gudipati  *
5483a36c61f9SKrishna Gudipati  *	return
5484a36c61f9SKrishna Gudipati  *		void
5485a36c61f9SKrishna Gudipati  *
5486a36c61f9SKrishna Gudipati  *	Special Considerations:
5487a36c61f9SKrishna Gudipati  *
5488a36c61f9SKrishna Gudipati  *	note
5489a36c61f9SKrishna Gudipati  */
5490a36c61f9SKrishna Gudipati static void
5491a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout(void *arg)
5492a36c61f9SKrishna Gudipati {
5493a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg;
5494a36c61f9SKrishna Gudipati 
5495a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT);
5496a36c61f9SKrishna Gudipati }
5497a36c61f9SKrishna Gudipati 
5498a36c61f9SKrishna Gudipati 
5499a36c61f9SKrishna Gudipati 
55005fbe25c7SJing Huang /*
5501a36c61f9SKrishna Gudipati  *  fcs_scn_public FCS state change notification public interfaces
5502a36c61f9SKrishna Gudipati  */
5503a36c61f9SKrishna Gudipati 
5504a36c61f9SKrishna Gudipati /*
5505a36c61f9SKrishna Gudipati  * Functions called by port/fab
5506a36c61f9SKrishna Gudipati  */
5507a36c61f9SKrishna Gudipati void
5508a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port)
5509a36c61f9SKrishna Gudipati {
5510a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
5511a36c61f9SKrishna Gudipati 
5512a36c61f9SKrishna Gudipati 	scn->port = port;
5513a36c61f9SKrishna Gudipati 	bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5514a36c61f9SKrishna Gudipati }
5515a36c61f9SKrishna Gudipati 
5516a36c61f9SKrishna Gudipati void
5517a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port)
5518a36c61f9SKrishna Gudipati {
5519a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
5520a36c61f9SKrishna Gudipati 
5521a36c61f9SKrishna Gudipati 	scn->port = port;
5522a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE);
5523a36c61f9SKrishna Gudipati }
5524a36c61f9SKrishna Gudipati 
5525a36c61f9SKrishna Gudipati void
5526bc0e2c2aSKrishna Gudipati bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *port)
5527a36c61f9SKrishna Gudipati {
5528a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
5529a36c61f9SKrishna Gudipati 
5530a36c61f9SKrishna Gudipati 	scn->port = port;
5531a36c61f9SKrishna Gudipati 	bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE);
5532a36c61f9SKrishna Gudipati }
5533a36c61f9SKrishna Gudipati 
5534a36c61f9SKrishna Gudipati static void
5535a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
5536a36c61f9SKrishna Gudipati {
5537a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
553861ba4394SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = port->fabric;
553961ba4394SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
554061ba4394SKrishna Gudipati 	struct list_head *qe;
5541a36c61f9SKrishna Gudipati 
5542a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpid);
5543a36c61f9SKrishna Gudipati 
55445fbe25c7SJing Huang 	/*
554561ba4394SKrishna Gudipati 	 * Ignore PID if it is of base port or of vports created on the
554661ba4394SKrishna Gudipati 	 * same base port. It is to avoid vports discovering base port or
554761ba4394SKrishna Gudipati 	 * other vports created on same base port as remote port
554861ba4394SKrishna Gudipati 	 */
554961ba4394SKrishna Gudipati 	if (rpid == fabric->bport.pid)
555061ba4394SKrishna Gudipati 		return;
555161ba4394SKrishna Gudipati 
555261ba4394SKrishna Gudipati 	list_for_each(qe, &fabric->vport_q) {
555361ba4394SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
555461ba4394SKrishna Gudipati 		if (vport->lport.pid == rpid)
555561ba4394SKrishna Gudipati 			return;
555661ba4394SKrishna Gudipati 	}
555761ba4394SKrishna Gudipati 	/*
5558a36c61f9SKrishna Gudipati 	 * If this is an unknown device, then it just came online.
5559a36c61f9SKrishna Gudipati 	 * Otherwise let rport handle the RSCN event.
5560a36c61f9SKrishna Gudipati 	 */
5561a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pid(port, rpid);
5562ee1a4a42SKrishna Gudipati 	if (!rport)
5563ee1a4a42SKrishna Gudipati 		rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid);
5564ee1a4a42SKrishna Gudipati 
5565a36c61f9SKrishna Gudipati 	if (rport == NULL) {
5566a36c61f9SKrishna Gudipati 		/*
5567a36c61f9SKrishna Gudipati 		 * If min cfg mode is enabled, we donot need to
5568a36c61f9SKrishna Gudipati 		 * discover any new rports.
5569a36c61f9SKrishna Gudipati 		 */
5570a36c61f9SKrishna Gudipati 		if (!__fcs_min_cfg(port->fcs))
5571a36c61f9SKrishna Gudipati 			rport = bfa_fcs_rport_create(port, rpid);
5572a36c61f9SKrishna Gudipati 	} else
5573a36c61f9SKrishna Gudipati 		bfa_fcs_rport_scn(rport);
5574a36c61f9SKrishna Gudipati }
5575a36c61f9SKrishna Gudipati 
55765fbe25c7SJing Huang /*
5577a36c61f9SKrishna Gudipati  * rscn format based PID comparison
5578a36c61f9SKrishna Gudipati  */
5579a36c61f9SKrishna Gudipati #define __fc_pid_match(__c0, __c1, __fmt)		\
5580a36c61f9SKrishna Gudipati 	(((__fmt) == FC_RSCN_FORMAT_FABRIC) ||		\
5581a36c61f9SKrishna Gudipati 	 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) &&		\
5582a36c61f9SKrishna Gudipati 	  ((__c0)[0] == (__c1)[0])) ||				\
5583a36c61f9SKrishna Gudipati 	 (((__fmt) == FC_RSCN_FORMAT_AREA) &&		\
5584a36c61f9SKrishna Gudipati 	  ((__c0)[0] == (__c1)[0]) &&				\
5585a36c61f9SKrishna Gudipati 	  ((__c0)[1] == (__c1)[1])))
5586a36c61f9SKrishna Gudipati 
5587a36c61f9SKrishna Gudipati static void
5588a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port,
5589a36c61f9SKrishna Gudipati 				enum fc_rscn_format format,
5590a36c61f9SKrishna Gudipati 				u32 rscn_pid)
5591a36c61f9SKrishna Gudipati {
5592a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
5593a36c61f9SKrishna Gudipati 	struct list_head        *qe, *qe_next;
5594a36c61f9SKrishna Gudipati 	u8        *c0, *c1;
5595a36c61f9SKrishna Gudipati 
5596a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, format);
5597a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rscn_pid);
5598a36c61f9SKrishna Gudipati 
5599a36c61f9SKrishna Gudipati 	c0 = (u8 *) &rscn_pid;
5600a36c61f9SKrishna Gudipati 
5601a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qe_next, &port->rport_q) {
5602a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
5603a36c61f9SKrishna Gudipati 		c1 = (u8 *) &rport->pid;
5604a36c61f9SKrishna Gudipati 		if (__fc_pid_match(c0, c1, format))
5605a36c61f9SKrishna Gudipati 			bfa_fcs_rport_scn(rport);
5606a36c61f9SKrishna Gudipati 	}
5607a36c61f9SKrishna Gudipati }
5608a36c61f9SKrishna Gudipati 
5609a36c61f9SKrishna Gudipati 
5610a36c61f9SKrishna Gudipati void
5611a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
5612a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u32 len)
5613a36c61f9SKrishna Gudipati {
5614a36c61f9SKrishna Gudipati 	struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1);
5615a36c61f9SKrishna Gudipati 	int             num_entries;
5616a36c61f9SKrishna Gudipati 	u32        rscn_pid;
5617a36c61f9SKrishna Gudipati 	bfa_boolean_t   nsquery = BFA_FALSE, found;
5618a36c61f9SKrishna Gudipati 	int             i = 0, j;
5619a36c61f9SKrishna Gudipati 
5620a36c61f9SKrishna Gudipati 	num_entries =
5621ba816ea8SJing Huang 		(be16_to_cpu(rscn->payldlen) -
5622a36c61f9SKrishna Gudipati 		 sizeof(u32)) / sizeof(rscn->event[0]);
5623a36c61f9SKrishna Gudipati 
5624a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, num_entries);
5625a36c61f9SKrishna Gudipati 
5626a36c61f9SKrishna Gudipati 	port->stats.num_rscn++;
5627a36c61f9SKrishna Gudipati 
5628a36c61f9SKrishna Gudipati 	bfa_fcs_lport_scn_send_ls_acc(port, fchs);
5629a36c61f9SKrishna Gudipati 
5630a36c61f9SKrishna Gudipati 	for (i = 0; i < num_entries; i++) {
5631a36c61f9SKrishna Gudipati 		rscn_pid = rscn->event[i].portid;
5632a36c61f9SKrishna Gudipati 
5633a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rscn->event[i].format);
5634a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rscn_pid);
5635a36c61f9SKrishna Gudipati 
5636a36c61f9SKrishna Gudipati 		/* check for duplicate entries in the list */
5637a36c61f9SKrishna Gudipati 		found = BFA_FALSE;
5638a36c61f9SKrishna Gudipati 		for (j = 0; j < i; j++) {
5639a36c61f9SKrishna Gudipati 			if (rscn->event[j].portid == rscn_pid) {
5640a36c61f9SKrishna Gudipati 				found = BFA_TRUE;
5641a36c61f9SKrishna Gudipati 				break;
5642a36c61f9SKrishna Gudipati 			}
5643a36c61f9SKrishna Gudipati 		}
5644a36c61f9SKrishna Gudipati 
5645a36c61f9SKrishna Gudipati 		/* if found in down the list, pid has been already processed */
5646a36c61f9SKrishna Gudipati 		if (found) {
5647a36c61f9SKrishna Gudipati 			bfa_trc(port->fcs, rscn_pid);
5648a36c61f9SKrishna Gudipati 			continue;
5649a36c61f9SKrishna Gudipati 		}
5650a36c61f9SKrishna Gudipati 
5651a36c61f9SKrishna Gudipati 		switch (rscn->event[i].format) {
5652a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_PORTID:
5653a36c61f9SKrishna Gudipati 			if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) {
5654a36c61f9SKrishna Gudipati 				/*
5655a36c61f9SKrishna Gudipati 				 * Ignore this event.
5656a36c61f9SKrishna Gudipati 				 * f/w would have processed it
5657a36c61f9SKrishna Gudipati 				 */
5658a36c61f9SKrishna Gudipati 				bfa_trc(port->fcs, rscn_pid);
5659a36c61f9SKrishna Gudipati 			} else {
5660a36c61f9SKrishna Gudipati 				port->stats.num_portid_rscn++;
5661a36c61f9SKrishna Gudipati 				bfa_fcs_lport_scn_portid_rscn(port, rscn_pid);
5662a36c61f9SKrishna Gudipati 			}
5663a36c61f9SKrishna Gudipati 		break;
5664a36c61f9SKrishna Gudipati 
5665a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_FABRIC:
5666a36c61f9SKrishna Gudipati 			if (rscn->event[i].qualifier ==
5667a36c61f9SKrishna Gudipati 					FC_FABRIC_NAME_RSCN_EVENT) {
5668a36c61f9SKrishna Gudipati 				bfa_fcs_lport_ms_fabric_rscn(port);
5669a36c61f9SKrishna Gudipati 				break;
5670a36c61f9SKrishna Gudipati 			}
5671a36c61f9SKrishna Gudipati 			/* !!!!!!!!! Fall Through !!!!!!!!!!!!! */
5672a36c61f9SKrishna Gudipati 
5673a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_AREA:
5674a36c61f9SKrishna Gudipati 		case FC_RSCN_FORMAT_DOMAIN:
5675a36c61f9SKrishna Gudipati 			nsquery = BFA_TRUE;
5676a36c61f9SKrishna Gudipati 			bfa_fcs_lport_scn_multiport_rscn(port,
5677a36c61f9SKrishna Gudipati 							rscn->event[i].format,
5678a36c61f9SKrishna Gudipati 							rscn_pid);
5679a36c61f9SKrishna Gudipati 			break;
5680a36c61f9SKrishna Gudipati 
5681a36c61f9SKrishna Gudipati 
5682a36c61f9SKrishna Gudipati 		default:
5683d4b671c5SJing Huang 			WARN_ON(1);
5684a36c61f9SKrishna Gudipati 			nsquery = BFA_TRUE;
5685a36c61f9SKrishna Gudipati 		}
5686a36c61f9SKrishna Gudipati 	}
5687a36c61f9SKrishna Gudipati 
56885fbe25c7SJing Huang 	/*
56895fbe25c7SJing Huang 	 * If any of area, domain or fabric RSCN is received, do a fresh
56905fbe25c7SJing Huang 	 * discovery to find new devices.
5691a36c61f9SKrishna Gudipati 	 */
5692a36c61f9SKrishna Gudipati 	if (nsquery)
5693a36c61f9SKrishna Gudipati 		bfa_fcs_lport_ns_query(port);
5694a36c61f9SKrishna Gudipati }
5695a36c61f9SKrishna Gudipati 
56965fbe25c7SJing Huang /*
5697a36c61f9SKrishna Gudipati  * BFA FCS port
5698a36c61f9SKrishna Gudipati  */
56995fbe25c7SJing Huang /*
5700a36c61f9SKrishna Gudipati  *  fcs_port_api BFA FCS port API
5701a36c61f9SKrishna Gudipati  */
5702a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *
5703a36c61f9SKrishna Gudipati bfa_fcs_get_base_port(struct bfa_fcs_s *fcs)
5704a36c61f9SKrishna Gudipati {
5705a36c61f9SKrishna Gudipati 	return &fcs->fabric.bport;
5706a36c61f9SKrishna Gudipati }
5707a36c61f9SKrishna Gudipati 
5708a36c61f9SKrishna Gudipati wwn_t
5709a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index,
5710a36c61f9SKrishna Gudipati 		int nrports, bfa_boolean_t bwwn)
5711a36c61f9SKrishna Gudipati {
5712a36c61f9SKrishna Gudipati 	struct list_head	*qh, *qe;
5713a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = NULL;
5714a36c61f9SKrishna Gudipati 	int	i;
5715a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs;
5716a36c61f9SKrishna Gudipati 
5717a36c61f9SKrishna Gudipati 	if (port == NULL || nrports == 0)
5718a36c61f9SKrishna Gudipati 		return (wwn_t) 0;
5719a36c61f9SKrishna Gudipati 
5720a36c61f9SKrishna Gudipati 	fcs = port->fcs;
5721a36c61f9SKrishna Gudipati 	bfa_trc(fcs, (u32) nrports);
5722a36c61f9SKrishna Gudipati 
5723a36c61f9SKrishna Gudipati 	i = 0;
5724a36c61f9SKrishna Gudipati 	qh = &port->rport_q;
5725a36c61f9SKrishna Gudipati 	qe = bfa_q_first(qh);
5726a36c61f9SKrishna Gudipati 
5727a36c61f9SKrishna Gudipati 	while ((qe != qh) && (i < nrports)) {
5728a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
5729f16a1750SMaggie Zhang 		if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
5730a36c61f9SKrishna Gudipati 			qe = bfa_q_next(qe);
5731a36c61f9SKrishna Gudipati 			bfa_trc(fcs, (u32) rport->pwwn);
5732a36c61f9SKrishna Gudipati 			bfa_trc(fcs, rport->pid);
5733a36c61f9SKrishna Gudipati 			bfa_trc(fcs, i);
5734a36c61f9SKrishna Gudipati 			continue;
5735a36c61f9SKrishna Gudipati 		}
5736a36c61f9SKrishna Gudipati 
5737a36c61f9SKrishna Gudipati 		if (bwwn) {
5738a36c61f9SKrishna Gudipati 			if (!memcmp(&wwn, &rport->pwwn, 8))
5739a36c61f9SKrishna Gudipati 				break;
5740a36c61f9SKrishna Gudipati 		} else {
5741a36c61f9SKrishna Gudipati 			if (i == index)
5742a36c61f9SKrishna Gudipati 				break;
5743a36c61f9SKrishna Gudipati 		}
5744a36c61f9SKrishna Gudipati 
5745a36c61f9SKrishna Gudipati 		i++;
5746a36c61f9SKrishna Gudipati 		qe = bfa_q_next(qe);
5747a36c61f9SKrishna Gudipati 	}
5748a36c61f9SKrishna Gudipati 
5749a36c61f9SKrishna Gudipati 	bfa_trc(fcs, i);
5750a36c61f9SKrishna Gudipati 	if (rport)
5751a36c61f9SKrishna Gudipati 		return rport->pwwn;
5752a36c61f9SKrishna Gudipati 	else
5753a36c61f9SKrishna Gudipati 		return (wwn_t) 0;
5754a36c61f9SKrishna Gudipati }
5755a36c61f9SKrishna Gudipati 
5756a36c61f9SKrishna Gudipati void
5757ee1a4a42SKrishna Gudipati bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
5758ee1a4a42SKrishna Gudipati 		struct bfa_rport_qualifier_s rports[], int *nrports)
5759a36c61f9SKrishna Gudipati {
5760a36c61f9SKrishna Gudipati 	struct list_head	*qh, *qe;
5761a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = NULL;
5762a36c61f9SKrishna Gudipati 	int	i;
5763a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs;
5764a36c61f9SKrishna Gudipati 
5765ee1a4a42SKrishna Gudipati 	if (port == NULL || rports == NULL || *nrports == 0)
5766a36c61f9SKrishna Gudipati 		return;
5767a36c61f9SKrishna Gudipati 
5768a36c61f9SKrishna Gudipati 	fcs = port->fcs;
5769a36c61f9SKrishna Gudipati 	bfa_trc(fcs, (u32) *nrports);
5770a36c61f9SKrishna Gudipati 
5771a36c61f9SKrishna Gudipati 	i = 0;
5772a36c61f9SKrishna Gudipati 	qh = &port->rport_q;
5773a36c61f9SKrishna Gudipati 	qe = bfa_q_first(qh);
5774a36c61f9SKrishna Gudipati 
5775a36c61f9SKrishna Gudipati 	while ((qe != qh) && (i < *nrports)) {
5776a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
5777f16a1750SMaggie Zhang 		if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
5778a36c61f9SKrishna Gudipati 			qe = bfa_q_next(qe);
5779a36c61f9SKrishna Gudipati 			bfa_trc(fcs, (u32) rport->pwwn);
5780a36c61f9SKrishna Gudipati 			bfa_trc(fcs, rport->pid);
5781a36c61f9SKrishna Gudipati 			bfa_trc(fcs, i);
5782a36c61f9SKrishna Gudipati 			continue;
5783a36c61f9SKrishna Gudipati 		}
5784a36c61f9SKrishna Gudipati 
5785ee1a4a42SKrishna Gudipati 		if (!rport->pwwn && !rport->pid) {
5786ee1a4a42SKrishna Gudipati 			qe = bfa_q_next(qe);
5787ee1a4a42SKrishna Gudipati 			continue;
5788ee1a4a42SKrishna Gudipati 		}
5789ee1a4a42SKrishna Gudipati 
5790ee1a4a42SKrishna Gudipati 		rports[i].pwwn = rport->pwwn;
5791ee1a4a42SKrishna Gudipati 		rports[i].pid = rport->pid;
5792a36c61f9SKrishna Gudipati 
5793a36c61f9SKrishna Gudipati 		i++;
5794a36c61f9SKrishna Gudipati 		qe = bfa_q_next(qe);
5795a36c61f9SKrishna Gudipati 	}
5796a36c61f9SKrishna Gudipati 
5797a36c61f9SKrishna Gudipati 	bfa_trc(fcs, i);
5798a36c61f9SKrishna Gudipati 	*nrports = i;
5799a36c61f9SKrishna Gudipati }
5800a36c61f9SKrishna Gudipati 
5801a36c61f9SKrishna Gudipati /*
5802a36c61f9SKrishna Gudipati  * Iterate's through all the rport's in the given port to
5803a36c61f9SKrishna Gudipati  * determine the maximum operating speed.
5804a36c61f9SKrishna Gudipati  *
5805a36c61f9SKrishna Gudipati  * !!!! To be used in TRL Functionality only !!!!
5806a36c61f9SKrishna Gudipati  */
5807a36c61f9SKrishna Gudipati bfa_port_speed_t
5808a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port)
5809a36c61f9SKrishna Gudipati {
5810a36c61f9SKrishna Gudipati 	struct list_head *qh, *qe;
5811a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = NULL;
5812a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs;
5813a36c61f9SKrishna Gudipati 	bfa_port_speed_t max_speed = 0;
5814a36c61f9SKrishna Gudipati 	struct bfa_port_attr_s port_attr;
5815a36c61f9SKrishna Gudipati 	bfa_port_speed_t port_speed, rport_speed;
5816a36c61f9SKrishna Gudipati 	bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa);
5817a36c61f9SKrishna Gudipati 
5818a36c61f9SKrishna Gudipati 
5819a36c61f9SKrishna Gudipati 	if (port == NULL)
5820a36c61f9SKrishna Gudipati 		return 0;
5821a36c61f9SKrishna Gudipati 
5822a36c61f9SKrishna Gudipati 	fcs = port->fcs;
5823a36c61f9SKrishna Gudipati 
5824a36c61f9SKrishna Gudipati 	/* Get Physical port's current speed */
5825a36c61f9SKrishna Gudipati 	bfa_fcport_get_attr(port->fcs->bfa, &port_attr);
5826a36c61f9SKrishna Gudipati 	port_speed = port_attr.speed;
5827a36c61f9SKrishna Gudipati 	bfa_trc(fcs, port_speed);
5828a36c61f9SKrishna Gudipati 
5829a36c61f9SKrishna Gudipati 	qh = &port->rport_q;
5830a36c61f9SKrishna Gudipati 	qe = bfa_q_first(qh);
5831a36c61f9SKrishna Gudipati 
5832a36c61f9SKrishna Gudipati 	while (qe != qh) {
5833a36c61f9SKrishna Gudipati 		rport = (struct bfa_fcs_rport_s *) qe;
5834f16a1750SMaggie Zhang 		if ((bfa_ntoh3b(rport->pid) > 0xFFF000) ||
5835d7be54ccSKrishna Gudipati 			(bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) ||
5836d7be54ccSKrishna Gudipati 			(rport->scsi_function != BFA_RPORT_TARGET)) {
5837a36c61f9SKrishna Gudipati 			qe = bfa_q_next(qe);
5838a36c61f9SKrishna Gudipati 			continue;
5839a36c61f9SKrishna Gudipati 		}
5840a36c61f9SKrishna Gudipati 
5841a36c61f9SKrishna Gudipati 		rport_speed = rport->rpf.rpsc_speed;
5842a36c61f9SKrishna Gudipati 		if ((trl_enabled) && (rport_speed ==
5843a36c61f9SKrishna Gudipati 			BFA_PORT_SPEED_UNKNOWN)) {
5844a36c61f9SKrishna Gudipati 			/* Use default ratelim speed setting */
5845a36c61f9SKrishna Gudipati 			rport_speed =
5846a36c61f9SKrishna Gudipati 				bfa_fcport_get_ratelim_speed(port->fcs->bfa);
5847a36c61f9SKrishna Gudipati 		}
5848a36c61f9SKrishna Gudipati 
5849d7be54ccSKrishna Gudipati 		if (rport_speed > max_speed)
5850a36c61f9SKrishna Gudipati 			max_speed = rport_speed;
5851a36c61f9SKrishna Gudipati 
5852a36c61f9SKrishna Gudipati 		qe = bfa_q_next(qe);
5853a36c61f9SKrishna Gudipati 	}
5854a36c61f9SKrishna Gudipati 
5855d7be54ccSKrishna Gudipati 	if (max_speed > port_speed)
5856d7be54ccSKrishna Gudipati 		max_speed = port_speed;
5857d7be54ccSKrishna Gudipati 
5858a36c61f9SKrishna Gudipati 	bfa_trc(fcs, max_speed);
5859a36c61f9SKrishna Gudipati 	return max_speed;
5860a36c61f9SKrishna Gudipati }
5861a36c61f9SKrishna Gudipati 
5862a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *
5863a36c61f9SKrishna Gudipati bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn)
5864a36c61f9SKrishna Gudipati {
5865a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
5866a36c61f9SKrishna Gudipati 	bfa_fcs_vf_t   *vf;
5867a36c61f9SKrishna Gudipati 
5868d4b671c5SJing Huang 	WARN_ON(fcs == NULL);
5869a36c61f9SKrishna Gudipati 
5870a36c61f9SKrishna Gudipati 	vf = bfa_fcs_vf_lookup(fcs, vf_id);
5871a36c61f9SKrishna Gudipati 	if (vf == NULL) {
5872a36c61f9SKrishna Gudipati 		bfa_trc(fcs, vf_id);
5873a36c61f9SKrishna Gudipati 		return NULL;
5874a36c61f9SKrishna Gudipati 	}
5875a36c61f9SKrishna Gudipati 
5876a36c61f9SKrishna Gudipati 	if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
5877a36c61f9SKrishna Gudipati 		return &vf->bport;
5878a36c61f9SKrishna Gudipati 
5879a36c61f9SKrishna Gudipati 	vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
5880a36c61f9SKrishna Gudipati 	if (vport)
5881a36c61f9SKrishna Gudipati 		return &vport->lport;
5882a36c61f9SKrishna Gudipati 
5883a36c61f9SKrishna Gudipati 	return NULL;
5884a36c61f9SKrishna Gudipati }
5885a36c61f9SKrishna Gudipati 
5886a36c61f9SKrishna Gudipati /*
5887a36c61f9SKrishna Gudipati  *  API corresponding to NPIV_VPORT_GETINFO.
5888a36c61f9SKrishna Gudipati  */
5889a36c61f9SKrishna Gudipati void
5890a36c61f9SKrishna Gudipati bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
5891a36c61f9SKrishna Gudipati 	 struct bfa_lport_info_s *port_info)
5892a36c61f9SKrishna Gudipati {
5893a36c61f9SKrishna Gudipati 
5894a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->fabric->fabric_name);
5895a36c61f9SKrishna Gudipati 
5896a36c61f9SKrishna Gudipati 	if (port->vport == NULL) {
5897a36c61f9SKrishna Gudipati 		/*
5898a36c61f9SKrishna Gudipati 		 * This is a Physical port
5899a36c61f9SKrishna Gudipati 		 */
5900a36c61f9SKrishna Gudipati 		port_info->port_type = BFA_LPORT_TYPE_PHYSICAL;
5901a36c61f9SKrishna Gudipati 
5902a36c61f9SKrishna Gudipati 		/*
5903a36c61f9SKrishna Gudipati 		 * @todo : need to fix the state & reason
5904a36c61f9SKrishna Gudipati 		 */
5905a36c61f9SKrishna Gudipati 		port_info->port_state = 0;
5906a36c61f9SKrishna Gudipati 		port_info->offline_reason = 0;
5907a36c61f9SKrishna Gudipati 
5908a36c61f9SKrishna Gudipati 		port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5909a36c61f9SKrishna Gudipati 		port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5910a36c61f9SKrishna Gudipati 
5911a36c61f9SKrishna Gudipati 		port_info->max_vports_supp =
5912a36c61f9SKrishna Gudipati 			bfa_lps_get_max_vport(port->fcs->bfa);
5913a36c61f9SKrishna Gudipati 		port_info->num_vports_inuse =
5914f7f73812SMaggie Zhang 			port->fabric->num_vports;
5915a36c61f9SKrishna Gudipati 		port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
5916a36c61f9SKrishna Gudipati 		port_info->num_rports_inuse = port->num_rports;
5917a36c61f9SKrishna Gudipati 	} else {
5918a36c61f9SKrishna Gudipati 		/*
5919a36c61f9SKrishna Gudipati 		 * This is a virtual port
5920a36c61f9SKrishna Gudipati 		 */
5921a36c61f9SKrishna Gudipati 		port_info->port_type = BFA_LPORT_TYPE_VIRTUAL;
5922a36c61f9SKrishna Gudipati 
5923a36c61f9SKrishna Gudipati 		/*
5924a36c61f9SKrishna Gudipati 		 * @todo : need to fix the state & reason
5925a36c61f9SKrishna Gudipati 		 */
5926a36c61f9SKrishna Gudipati 		port_info->port_state = 0;
5927a36c61f9SKrishna Gudipati 		port_info->offline_reason = 0;
5928a36c61f9SKrishna Gudipati 
5929a36c61f9SKrishna Gudipati 		port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5930a36c61f9SKrishna Gudipati 		port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5931a36c61f9SKrishna Gudipati 	}
5932a36c61f9SKrishna Gudipati }
5933a36c61f9SKrishna Gudipati 
5934a36c61f9SKrishna Gudipati void
5935a36c61f9SKrishna Gudipati bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port,
5936a36c61f9SKrishna Gudipati 	 struct bfa_lport_stats_s *port_stats)
5937a36c61f9SKrishna Gudipati {
5938a36c61f9SKrishna Gudipati 	*port_stats = fcs_port->stats;
5939a36c61f9SKrishna Gudipati }
5940a36c61f9SKrishna Gudipati 
5941a36c61f9SKrishna Gudipati void
5942a36c61f9SKrishna Gudipati bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port)
5943a36c61f9SKrishna Gudipati {
59446a18b167SJing Huang 	memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s));
5945a36c61f9SKrishna Gudipati }
5946a36c61f9SKrishna Gudipati 
59475fbe25c7SJing Huang /*
5948bc0e2c2aSKrishna Gudipati  * Let new loop map create missing rports
5949bc0e2c2aSKrishna Gudipati  */
5950bc0e2c2aSKrishna Gudipati void
5951bc0e2c2aSKrishna Gudipati bfa_fcs_lport_lip_scn_online(struct bfa_fcs_lport_s *port)
5952bc0e2c2aSKrishna Gudipati {
5953bc0e2c2aSKrishna Gudipati 	bfa_fcs_lport_loop_online(port);
5954bc0e2c2aSKrishna Gudipati }
5955bc0e2c2aSKrishna Gudipati 
5956bc0e2c2aSKrishna Gudipati /*
5957a36c61f9SKrishna Gudipati  * FCS virtual port state machine
5958a36c61f9SKrishna Gudipati  */
5959a36c61f9SKrishna Gudipati 
5960a36c61f9SKrishna Gudipati #define __vport_fcs(__vp)       ((__vp)->lport.fcs)
5961a36c61f9SKrishna Gudipati #define __vport_pwwn(__vp)      ((__vp)->lport.port_cfg.pwwn)
5962a36c61f9SKrishna Gudipati #define __vport_nwwn(__vp)      ((__vp)->lport.port_cfg.nwwn)
5963a36c61f9SKrishna Gudipati #define __vport_bfa(__vp)       ((__vp)->lport.fcs->bfa)
5964a36c61f9SKrishna Gudipati #define __vport_fcid(__vp)      ((__vp)->lport.pid)
5965a36c61f9SKrishna Gudipati #define __vport_fabric(__vp)    ((__vp)->lport.fabric)
5966a36c61f9SKrishna Gudipati #define __vport_vfid(__vp)      ((__vp)->lport.fabric->vf_id)
5967a36c61f9SKrishna Gudipati 
5968a36c61f9SKrishna Gudipati #define BFA_FCS_VPORT_MAX_RETRIES  5
5969a36c61f9SKrishna Gudipati /*
5970a36c61f9SKrishna Gudipati  * Forward declarations
5971a36c61f9SKrishna Gudipati  */
5972a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport);
5973a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_timeout(void *vport_arg);
5974a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport);
5975a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport);
5976a36c61f9SKrishna Gudipati 
59775fbe25c7SJing Huang /*
5978a36c61f9SKrishna Gudipati  *  fcs_vport_sm FCS virtual port state machine
5979a36c61f9SKrishna Gudipati  */
5980a36c61f9SKrishna Gudipati 
59815fbe25c7SJing Huang /*
5982a36c61f9SKrishna Gudipati  * VPort State Machine events
5983a36c61f9SKrishna Gudipati  */
5984a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event {
5985a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_CREATE = 1,	/*  vport create event */
5986a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_DELETE = 2,	/*  vport delete event */
5987a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_START = 3,	/*  vport start request */
5988a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_STOP = 4,	/*  stop: unsupported */
5989a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_ONLINE = 5,	/*  fabric online */
5990a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_OFFLINE = 6,	/*  fabric offline event */
5991a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_FRMSENT = 7,	/*  fdisc/logo sent events */
5992a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_OK = 8,	/*  good response */
5993a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_ERROR = 9,	/*  error/bad response */
5994a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_TIMEOUT = 10,	/*  delay timer event */
5995a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_DELCOMP = 11,	/*  lport delete completion */
5996a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12,	/*  Dup wnn error*/
5997a36c61f9SKrishna Gudipati 	BFA_FCS_VPORT_SM_RSP_FAILED = 13,	/*  non-retryable failure */
5998dd5aaf45SKrishna Gudipati 	BFA_FCS_VPORT_SM_STOPCOMP = 14,	/* vport delete completion */
5999f2a0cc3fSVijaya Mohan Guvva 	BFA_FCS_VPORT_SM_FABRIC_MAX = 15, /* max vports on fabric */
6000a36c61f9SKrishna Gudipati };
6001a36c61f9SKrishna Gudipati 
6002a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
6003a36c61f9SKrishna Gudipati 					enum bfa_fcs_vport_event event);
6004a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
6005a36c61f9SKrishna Gudipati 					 enum bfa_fcs_vport_event event);
6006a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
6007a36c61f9SKrishna Gudipati 					 enum bfa_fcs_vport_event event);
6008a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
6009a36c61f9SKrishna Gudipati 				       enum bfa_fcs_vport_event event);
6010a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
6011a36c61f9SKrishna Gudipati 					     enum bfa_fcs_vport_event event);
6012d7be54ccSKrishna Gudipati static void	bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
6013d7be54ccSKrishna Gudipati 					enum bfa_fcs_vport_event event);
6014a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
6015a36c61f9SKrishna Gudipati 					enum bfa_fcs_vport_event event);
6016a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
6017a36c61f9SKrishna Gudipati 					  enum bfa_fcs_vport_event event);
6018a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
6019a36c61f9SKrishna Gudipati 					 enum bfa_fcs_vport_event event);
6020a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
6021a36c61f9SKrishna Gudipati 				      enum bfa_fcs_vport_event event);
6022a36c61f9SKrishna Gudipati static void     bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
6023a36c61f9SKrishna Gudipati 				      enum bfa_fcs_vport_event event);
6024dd5aaf45SKrishna Gudipati static void	bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
6025dd5aaf45SKrishna Gudipati 					enum bfa_fcs_vport_event event);
6026dd5aaf45SKrishna Gudipati static void	bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
6027dd5aaf45SKrishna Gudipati 					enum bfa_fcs_vport_event event);
6028a36c61f9SKrishna Gudipati 
6029a36c61f9SKrishna Gudipati static struct bfa_sm_table_s  vport_sm_table[] = {
6030a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT},
6031a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED},
6032a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE},
6033a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC},
6034a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY},
6035d7be54ccSKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT},
6036a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE},
6037a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING},
6038a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP},
6039a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO},
6040a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR}
6041a36c61f9SKrishna Gudipati };
6042a36c61f9SKrishna Gudipati 
60435fbe25c7SJing Huang /*
6044a36c61f9SKrishna Gudipati  * Beginning state.
6045a36c61f9SKrishna Gudipati  */
6046a36c61f9SKrishna Gudipati static void
6047a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
6048a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
6049a36c61f9SKrishna Gudipati {
6050a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6051a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6052a36c61f9SKrishna Gudipati 
6053a36c61f9SKrishna Gudipati 	switch (event) {
6054a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_CREATE:
6055a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
6056a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_addvport(__vport_fabric(vport), vport);
6057a36c61f9SKrishna Gudipati 		break;
6058a36c61f9SKrishna Gudipati 
6059a36c61f9SKrishna Gudipati 	default:
6060a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6061a36c61f9SKrishna Gudipati 	}
6062a36c61f9SKrishna Gudipati }
6063a36c61f9SKrishna Gudipati 
60645fbe25c7SJing Huang /*
6065a36c61f9SKrishna Gudipati  * Created state - a start event is required to start up the state machine.
6066a36c61f9SKrishna Gudipati  */
6067a36c61f9SKrishna Gudipati static void
6068a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
6069a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
6070a36c61f9SKrishna Gudipati {
6071a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6072a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6073a36c61f9SKrishna Gudipati 
6074a36c61f9SKrishna Gudipati 	switch (event) {
6075a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_START:
6076f7f73812SMaggie Zhang 		if (bfa_sm_cmp_state(__vport_fabric(vport),
6077f7f73812SMaggie Zhang 					bfa_fcs_fabric_sm_online)
6078a36c61f9SKrishna Gudipati 		    && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) {
6079a36c61f9SKrishna Gudipati 			bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
6080a36c61f9SKrishna Gudipati 			bfa_fcs_vport_do_fdisc(vport);
6081a36c61f9SKrishna Gudipati 		} else {
60825fbe25c7SJing Huang 			/*
6083a36c61f9SKrishna Gudipati 			 * Fabric is offline or not NPIV capable, stay in
6084a36c61f9SKrishna Gudipati 			 * offline state.
6085a36c61f9SKrishna Gudipati 			 */
6086a36c61f9SKrishna Gudipati 			vport->vport_stats.fab_no_npiv++;
6087a36c61f9SKrishna Gudipati 			bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6088a36c61f9SKrishna Gudipati 		}
6089a36c61f9SKrishna Gudipati 		break;
6090a36c61f9SKrishna Gudipati 
6091a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
6092a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6093a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
6094a36c61f9SKrishna Gudipati 		break;
6095a36c61f9SKrishna Gudipati 
6096a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_ONLINE:
6097a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
60985fbe25c7SJing Huang 		/*
6099a36c61f9SKrishna Gudipati 		 * Ignore ONLINE/OFFLINE events from fabric
6100a36c61f9SKrishna Gudipati 		 * till vport is started.
6101a36c61f9SKrishna Gudipati 		 */
6102a36c61f9SKrishna Gudipati 		break;
6103a36c61f9SKrishna Gudipati 
6104a36c61f9SKrishna Gudipati 	default:
6105a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6106a36c61f9SKrishna Gudipati 	}
6107a36c61f9SKrishna Gudipati }
6108a36c61f9SKrishna Gudipati 
61095fbe25c7SJing Huang /*
6110a36c61f9SKrishna Gudipati  * Offline state - awaiting ONLINE event from fabric SM.
6111a36c61f9SKrishna Gudipati  */
6112a36c61f9SKrishna Gudipati static void
6113a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
6114a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
6115a36c61f9SKrishna Gudipati {
6116a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6117a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6118a36c61f9SKrishna Gudipati 
6119a36c61f9SKrishna Gudipati 	switch (event) {
6120a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
6121a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6122a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
6123a36c61f9SKrishna Gudipati 		break;
6124a36c61f9SKrishna Gudipati 
6125a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_ONLINE:
6126a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
6127a36c61f9SKrishna Gudipati 		vport->fdisc_retries = 0;
6128a36c61f9SKrishna Gudipati 		bfa_fcs_vport_do_fdisc(vport);
6129a36c61f9SKrishna Gudipati 		break;
6130a36c61f9SKrishna Gudipati 
6131dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOP:
6132dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6133dd5aaf45SKrishna Gudipati 		bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
6134dd5aaf45SKrishna Gudipati 		break;
6135dd5aaf45SKrishna Gudipati 
6136a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
6137a36c61f9SKrishna Gudipati 		/*
6138a36c61f9SKrishna Gudipati 		 * This can happen if the vport couldn't be initialzied
6139a36c61f9SKrishna Gudipati 		 * due the fact that the npiv was not enabled on the switch.
6140a36c61f9SKrishna Gudipati 		 * In that case we will put the vport in offline state.
6141a36c61f9SKrishna Gudipati 		 * However, the link can go down and cause the this event to
6142a36c61f9SKrishna Gudipati 		 * be sent when we are already offline. Ignore it.
6143a36c61f9SKrishna Gudipati 		 */
6144a36c61f9SKrishna Gudipati 		break;
6145a36c61f9SKrishna Gudipati 
6146a36c61f9SKrishna Gudipati 	default:
6147a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6148a36c61f9SKrishna Gudipati 	}
6149a36c61f9SKrishna Gudipati }
6150a36c61f9SKrishna Gudipati 
6151a36c61f9SKrishna Gudipati 
61525fbe25c7SJing Huang /*
6153a36c61f9SKrishna Gudipati  * FDISC is sent and awaiting reply from fabric.
6154a36c61f9SKrishna Gudipati  */
6155a36c61f9SKrishna Gudipati static void
6156a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
6157a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
6158a36c61f9SKrishna Gudipati {
6159a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6160a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6161a36c61f9SKrishna Gudipati 
6162a36c61f9SKrishna Gudipati 	switch (event) {
6163a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
6164d7be54ccSKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait);
6165a36c61f9SKrishna Gudipati 		break;
6166a36c61f9SKrishna Gudipati 
6167a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
6168a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6169f7f73812SMaggie Zhang 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
6170a36c61f9SKrishna Gudipati 		break;
6171a36c61f9SKrishna Gudipati 
6172a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
6173a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_online);
6174a36c61f9SKrishna Gudipati 		bfa_fcs_lport_online(&vport->lport);
6175a36c61f9SKrishna Gudipati 		break;
6176a36c61f9SKrishna Gudipati 
6177a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
6178a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry);
6179a36c61f9SKrishna Gudipati 		bfa_timer_start(__vport_bfa(vport), &vport->timer,
6180a36c61f9SKrishna Gudipati 				    bfa_fcs_vport_timeout, vport,
6181a36c61f9SKrishna Gudipati 				    BFA_FCS_RETRY_TIMEOUT);
6182a36c61f9SKrishna Gudipati 		break;
6183a36c61f9SKrishna Gudipati 
6184a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_FAILED:
6185f2a0cc3fSVijaya Mohan Guvva 	case BFA_FCS_VPORT_SM_FABRIC_MAX:
6186a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6187a36c61f9SKrishna Gudipati 		break;
6188a36c61f9SKrishna Gudipati 
6189a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
6190a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_error);
6191a36c61f9SKrishna Gudipati 		break;
6192a36c61f9SKrishna Gudipati 
6193a36c61f9SKrishna Gudipati 	default:
6194a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6195a36c61f9SKrishna Gudipati 	}
6196a36c61f9SKrishna Gudipati }
6197a36c61f9SKrishna Gudipati 
61985fbe25c7SJing Huang /*
6199a36c61f9SKrishna Gudipati  * FDISC attempt failed - a timer is active to retry FDISC.
6200a36c61f9SKrishna Gudipati  */
6201a36c61f9SKrishna Gudipati static void
6202a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
6203a36c61f9SKrishna Gudipati 			     enum bfa_fcs_vport_event event)
6204a36c61f9SKrishna Gudipati {
6205a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6206a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6207a36c61f9SKrishna Gudipati 
6208a36c61f9SKrishna Gudipati 	switch (event) {
6209a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
6210a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6211a36c61f9SKrishna Gudipati 		bfa_timer_stop(&vport->timer);
6212a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
6213a36c61f9SKrishna Gudipati 		break;
6214a36c61f9SKrishna Gudipati 
6215a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
6216a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6217a36c61f9SKrishna Gudipati 		bfa_timer_stop(&vport->timer);
6218a36c61f9SKrishna Gudipati 		break;
6219a36c61f9SKrishna Gudipati 
6220a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_TIMEOUT:
6221a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
6222a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_retries++;
6223a36c61f9SKrishna Gudipati 		vport->fdisc_retries++;
6224a36c61f9SKrishna Gudipati 		bfa_fcs_vport_do_fdisc(vport);
6225a36c61f9SKrishna Gudipati 		break;
6226a36c61f9SKrishna Gudipati 
6227a36c61f9SKrishna Gudipati 	default:
6228a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6229a36c61f9SKrishna Gudipati 	}
6230a36c61f9SKrishna Gudipati }
6231a36c61f9SKrishna Gudipati 
62325fbe25c7SJing Huang /*
6233d7be54ccSKrishna Gudipati  * FDISC is in progress and we got a vport delete request -
6234d7be54ccSKrishna Gudipati  * this is a wait state while we wait for fdisc response and
6235d7be54ccSKrishna Gudipati  * we will transition to the appropriate state - on rsp status.
6236d7be54ccSKrishna Gudipati  */
6237d7be54ccSKrishna Gudipati static void
6238d7be54ccSKrishna Gudipati bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
6239d7be54ccSKrishna Gudipati 				enum bfa_fcs_vport_event event)
6240d7be54ccSKrishna Gudipati {
6241d7be54ccSKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6242d7be54ccSKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6243d7be54ccSKrishna Gudipati 
6244d7be54ccSKrishna Gudipati 	switch (event) {
6245d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
6246d7be54ccSKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
6247d7be54ccSKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
6248d7be54ccSKrishna Gudipati 		break;
6249d7be54ccSKrishna Gudipati 
6250d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
6251d7be54ccSKrishna Gudipati 		break;
6252d7be54ccSKrishna Gudipati 
6253d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
6254d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
6255d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_FAILED:
6256f2a0cc3fSVijaya Mohan Guvva 	case BFA_FCS_VPORT_SM_FABRIC_MAX:
6257d7be54ccSKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
6258d7be54ccSKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6259d7be54ccSKrishna Gudipati 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
6260d7be54ccSKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
6261d7be54ccSKrishna Gudipati 		break;
6262d7be54ccSKrishna Gudipati 
6263d7be54ccSKrishna Gudipati 	default:
6264d7be54ccSKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6265d7be54ccSKrishna Gudipati 	}
6266d7be54ccSKrishna Gudipati }
6267d7be54ccSKrishna Gudipati 
6268d7be54ccSKrishna Gudipati /*
6269a36c61f9SKrishna Gudipati  * Vport is online (FDISC is complete).
6270a36c61f9SKrishna Gudipati  */
6271a36c61f9SKrishna Gudipati static void
6272a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
6273a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
6274a36c61f9SKrishna Gudipati {
6275a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6276a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6277a36c61f9SKrishna Gudipati 
6278a36c61f9SKrishna Gudipati 	switch (event) {
6279a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
6280a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
6281a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
6282a36c61f9SKrishna Gudipati 		break;
6283a36c61f9SKrishna Gudipati 
6284dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOP:
6285dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping);
6286dd5aaf45SKrishna Gudipati 		bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
6287dd5aaf45SKrishna Gudipati 		break;
6288dd5aaf45SKrishna Gudipati 
6289a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
6290a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6291f7f73812SMaggie Zhang 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
6292a36c61f9SKrishna Gudipati 		bfa_fcs_lport_offline(&vport->lport);
6293a36c61f9SKrishna Gudipati 		break;
6294a36c61f9SKrishna Gudipati 
6295a36c61f9SKrishna Gudipati 	default:
6296a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6297a36c61f9SKrishna Gudipati 	}
6298a36c61f9SKrishna Gudipati }
6299a36c61f9SKrishna Gudipati 
63005fbe25c7SJing Huang /*
6301dd5aaf45SKrishna Gudipati  * Vport is being stopped - awaiting lport stop completion to send
6302dd5aaf45SKrishna Gudipati  * LOGO to fabric.
6303dd5aaf45SKrishna Gudipati  */
6304dd5aaf45SKrishna Gudipati static void
6305dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
6306dd5aaf45SKrishna Gudipati 			  enum bfa_fcs_vport_event event)
6307dd5aaf45SKrishna Gudipati {
6308dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6309dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6310dd5aaf45SKrishna Gudipati 
6311dd5aaf45SKrishna Gudipati 	switch (event) {
6312dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOPCOMP:
6313dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop);
6314dd5aaf45SKrishna Gudipati 		bfa_fcs_vport_do_logo(vport);
6315dd5aaf45SKrishna Gudipati 		break;
6316dd5aaf45SKrishna Gudipati 
6317dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
6318dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6319dd5aaf45SKrishna Gudipati 		break;
6320dd5aaf45SKrishna Gudipati 
6321dd5aaf45SKrishna Gudipati 	default:
6322dd5aaf45SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6323dd5aaf45SKrishna Gudipati 	}
6324dd5aaf45SKrishna Gudipati }
6325dd5aaf45SKrishna Gudipati 
6326dd5aaf45SKrishna Gudipati /*
6327a36c61f9SKrishna Gudipati  * Vport is being deleted - awaiting lport delete completion to send
6328a36c61f9SKrishna Gudipati  * LOGO to fabric.
6329a36c61f9SKrishna Gudipati  */
6330a36c61f9SKrishna Gudipati static void
6331a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
6332a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
6333a36c61f9SKrishna Gudipati {
6334a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6335a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6336a36c61f9SKrishna Gudipati 
6337a36c61f9SKrishna Gudipati 	switch (event) {
6338a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
6339a36c61f9SKrishna Gudipati 		break;
6340a36c61f9SKrishna Gudipati 
6341a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELCOMP:
6342a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
6343a36c61f9SKrishna Gudipati 		bfa_fcs_vport_do_logo(vport);
6344a36c61f9SKrishna Gudipati 		break;
6345a36c61f9SKrishna Gudipati 
6346a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
6347a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6348a36c61f9SKrishna Gudipati 		break;
6349a36c61f9SKrishna Gudipati 
6350a36c61f9SKrishna Gudipati 	default:
6351a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6352a36c61f9SKrishna Gudipati 	}
6353a36c61f9SKrishna Gudipati }
6354a36c61f9SKrishna Gudipati 
63555fbe25c7SJing Huang /*
6356a36c61f9SKrishna Gudipati  * Error State.
6357a36c61f9SKrishna Gudipati  * This state will be set when the Vport Creation fails due
6358a36c61f9SKrishna Gudipati  * to errors like Dup WWN. In this state only operation allowed
6359a36c61f9SKrishna Gudipati  * is a Vport Delete.
6360a36c61f9SKrishna Gudipati  */
6361a36c61f9SKrishna Gudipati static void
6362a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
6363a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
6364a36c61f9SKrishna Gudipati {
6365a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6366a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6367a36c61f9SKrishna Gudipati 
6368a36c61f9SKrishna Gudipati 	switch (event) {
6369a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
6370a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6371a36c61f9SKrishna Gudipati 		bfa_fcs_lport_delete(&vport->lport);
6372a36c61f9SKrishna Gudipati 		break;
6373a36c61f9SKrishna Gudipati 
6374a36c61f9SKrishna Gudipati 	default:
6375a36c61f9SKrishna Gudipati 		bfa_trc(__vport_fcs(vport), event);
6376a36c61f9SKrishna Gudipati 	}
6377a36c61f9SKrishna Gudipati }
6378a36c61f9SKrishna Gudipati 
63795fbe25c7SJing Huang /*
6380a36c61f9SKrishna Gudipati  * Lport cleanup is in progress since vport is being deleted. Fabric is
6381a36c61f9SKrishna Gudipati  * offline, so no LOGO is needed to complete vport deletion.
6382a36c61f9SKrishna Gudipati  */
6383a36c61f9SKrishna Gudipati static void
6384a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
6385a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
6386a36c61f9SKrishna Gudipati {
6387a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6388a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6389a36c61f9SKrishna Gudipati 
6390a36c61f9SKrishna Gudipati 	switch (event) {
6391a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELCOMP:
6392a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
6393a36c61f9SKrishna Gudipati 		bfa_fcs_vport_free(vport);
6394a36c61f9SKrishna Gudipati 		break;
6395a36c61f9SKrishna Gudipati 
6396dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_STOPCOMP:
6397dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
6398dd5aaf45SKrishna Gudipati 		break;
6399dd5aaf45SKrishna Gudipati 
6400a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
6401a36c61f9SKrishna Gudipati 		break;
6402a36c61f9SKrishna Gudipati 
6403a36c61f9SKrishna Gudipati 	default:
6404a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6405a36c61f9SKrishna Gudipati 	}
6406a36c61f9SKrishna Gudipati }
6407a36c61f9SKrishna Gudipati 
64085fbe25c7SJing Huang /*
6409dd5aaf45SKrishna Gudipati  * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup
6410dd5aaf45SKrishna Gudipati  * is done.
6411dd5aaf45SKrishna Gudipati  */
6412dd5aaf45SKrishna Gudipati static void
6413dd5aaf45SKrishna Gudipati bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
6414dd5aaf45SKrishna Gudipati 			       enum bfa_fcs_vport_event event)
6415dd5aaf45SKrishna Gudipati {
6416dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6417dd5aaf45SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6418dd5aaf45SKrishna Gudipati 
6419dd5aaf45SKrishna Gudipati 	switch (event) {
6420dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
6421dd5aaf45SKrishna Gudipati 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
6422dd5aaf45SKrishna Gudipati 		/*
6423dd5aaf45SKrishna Gudipati 		 * !!! fall through !!!
6424dd5aaf45SKrishna Gudipati 		 */
6425dd5aaf45SKrishna Gudipati 
6426dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
6427dd5aaf45SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
6428dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
6429dd5aaf45SKrishna Gudipati 		break;
6430dd5aaf45SKrishna Gudipati 
6431dd5aaf45SKrishna Gudipati 	default:
6432dd5aaf45SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6433dd5aaf45SKrishna Gudipati 	}
6434dd5aaf45SKrishna Gudipati }
6435dd5aaf45SKrishna Gudipati 
6436dd5aaf45SKrishna Gudipati /*
6437a36c61f9SKrishna Gudipati  * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
6438a36c61f9SKrishna Gudipati  * is done.
6439a36c61f9SKrishna Gudipati  */
6440a36c61f9SKrishna Gudipati static void
6441a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
6442a36c61f9SKrishna Gudipati 			enum bfa_fcs_vport_event event)
6443a36c61f9SKrishna Gudipati {
6444a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6445a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), event);
6446a36c61f9SKrishna Gudipati 
6447a36c61f9SKrishna Gudipati 	switch (event) {
6448a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_OFFLINE:
6449f7f73812SMaggie Zhang 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
6450a36c61f9SKrishna Gudipati 		/*
6451a36c61f9SKrishna Gudipati 		 * !!! fall through !!!
6452a36c61f9SKrishna Gudipati 		 */
6453a36c61f9SKrishna Gudipati 
6454a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_OK:
6455a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_RSP_ERROR:
6456a36c61f9SKrishna Gudipati 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
6457a36c61f9SKrishna Gudipati 		bfa_fcs_vport_free(vport);
6458a36c61f9SKrishna Gudipati 		break;
6459a36c61f9SKrishna Gudipati 
6460a36c61f9SKrishna Gudipati 	case BFA_FCS_VPORT_SM_DELETE:
6461a36c61f9SKrishna Gudipati 		break;
6462a36c61f9SKrishna Gudipati 
6463a36c61f9SKrishna Gudipati 	default:
6464a36c61f9SKrishna Gudipati 		bfa_sm_fault(__vport_fcs(vport), event);
6465a36c61f9SKrishna Gudipati 	}
6466a36c61f9SKrishna Gudipati }
6467a36c61f9SKrishna Gudipati 
6468a36c61f9SKrishna Gudipati 
6469a36c61f9SKrishna Gudipati 
64705fbe25c7SJing Huang /*
6471a36c61f9SKrishna Gudipati  *  fcs_vport_private FCS virtual port private functions
6472a36c61f9SKrishna Gudipati  */
64735fbe25c7SJing Huang /*
64747826f304SKrishna Gudipati  * Send AEN notification
64757826f304SKrishna Gudipati  */
64767826f304SKrishna Gudipati static void
64777826f304SKrishna Gudipati bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port,
64787826f304SKrishna Gudipati 		       enum bfa_lport_aen_event event)
64797826f304SKrishna Gudipati {
64807826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
64817826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
64827826f304SKrishna Gudipati 
64837826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
64847826f304SKrishna Gudipati 	if (!aen_entry)
64857826f304SKrishna Gudipati 		return;
64867826f304SKrishna Gudipati 
64877826f304SKrishna Gudipati 	aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
64887826f304SKrishna Gudipati 	aen_entry->aen_data.lport.roles = port->port_cfg.roles;
64897826f304SKrishna Gudipati 	aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
64907826f304SKrishna Gudipati 					bfa_fcs_get_base_port(port->fcs));
64917826f304SKrishna Gudipati 	aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
64927826f304SKrishna Gudipati 
64937826f304SKrishna Gudipati 	/* Send the AEN notification */
64947826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
64957826f304SKrishna Gudipati 				  BFA_AEN_CAT_LPORT, event);
64967826f304SKrishna Gudipati }
64977826f304SKrishna Gudipati 
64987826f304SKrishna Gudipati /*
6499a36c61f9SKrishna Gudipati  * This routine will be called to send a FDISC command.
6500a36c61f9SKrishna Gudipati  */
6501a36c61f9SKrishna Gudipati static void
6502a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
6503a36c61f9SKrishna Gudipati {
6504a36c61f9SKrishna Gudipati 	bfa_lps_fdisc(vport->lps, vport,
6505a36c61f9SKrishna Gudipati 		bfa_fcport_get_maxfrsize(__vport_bfa(vport)),
6506a36c61f9SKrishna Gudipati 		__vport_pwwn(vport), __vport_nwwn(vport));
6507a36c61f9SKrishna Gudipati 	vport->vport_stats.fdisc_sent++;
6508a36c61f9SKrishna Gudipati }
6509a36c61f9SKrishna Gudipati 
6510a36c61f9SKrishna Gudipati static void
6511a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
6512a36c61f9SKrishna Gudipati {
6513f7f73812SMaggie Zhang 	u8		lsrjt_rsn = vport->lps->lsrjt_rsn;
6514f7f73812SMaggie Zhang 	u8		lsrjt_expl = vport->lps->lsrjt_expl;
6515a36c61f9SKrishna Gudipati 
6516a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), lsrjt_rsn);
6517a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), lsrjt_expl);
6518a36c61f9SKrishna Gudipati 
6519a36c61f9SKrishna Gudipati 	/* For certain reason codes, we don't want to retry. */
6520f7f73812SMaggie Zhang 	switch (vport->lps->lsrjt_expl) {
6521a36c61f9SKrishna Gudipati 	case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */
6522a36c61f9SKrishna Gudipati 	case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
6523a36c61f9SKrishna Gudipati 		if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
6524a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
65257826f304SKrishna Gudipati 		else {
65267826f304SKrishna Gudipati 			bfa_fcs_vport_aen_post(&vport->lport,
65277826f304SKrishna Gudipati 					BFA_LPORT_AEN_NPIV_DUP_WWN);
6528a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN);
65297826f304SKrishna Gudipati 		}
6530a36c61f9SKrishna Gudipati 		break;
6531a36c61f9SKrishna Gudipati 
6532a36c61f9SKrishna Gudipati 	case FC_LS_RJT_EXP_INSUFF_RES:
6533a36c61f9SKrishna Gudipati 		/*
6534a36c61f9SKrishna Gudipati 		 * This means max logins per port/switch setting on the
6535a36c61f9SKrishna Gudipati 		 * switch was exceeded.
6536a36c61f9SKrishna Gudipati 		 */
6537a36c61f9SKrishna Gudipati 		if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
6538a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
65397826f304SKrishna Gudipati 		else {
65407826f304SKrishna Gudipati 			bfa_fcs_vport_aen_post(&vport->lport,
65417826f304SKrishna Gudipati 					BFA_LPORT_AEN_NPIV_FABRIC_MAX);
6542f2a0cc3fSVijaya Mohan Guvva 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_FABRIC_MAX);
65437826f304SKrishna Gudipati 		}
6544a36c61f9SKrishna Gudipati 		break;
6545a36c61f9SKrishna Gudipati 
6546a36c61f9SKrishna Gudipati 	default:
65477826f304SKrishna Gudipati 		if (vport->fdisc_retries == 0)
65487826f304SKrishna Gudipati 			bfa_fcs_vport_aen_post(&vport->lport,
65497826f304SKrishna Gudipati 					BFA_LPORT_AEN_NPIV_UNKNOWN);
6550a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6551a36c61f9SKrishna Gudipati 	}
6552a36c61f9SKrishna Gudipati }
6553a36c61f9SKrishna Gudipati 
65545fbe25c7SJing Huang /*
6555a36c61f9SKrishna Gudipati  *	Called to send a logout to the fabric. Used when a V-Port is
6556a36c61f9SKrishna Gudipati  *	deleted/stopped.
6557a36c61f9SKrishna Gudipati  */
6558a36c61f9SKrishna Gudipati static void
6559a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport)
6560a36c61f9SKrishna Gudipati {
6561a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6562a36c61f9SKrishna Gudipati 
6563a36c61f9SKrishna Gudipati 	vport->vport_stats.logo_sent++;
6564a36c61f9SKrishna Gudipati 	bfa_lps_fdisclogo(vport->lps);
6565a36c61f9SKrishna Gudipati }
6566a36c61f9SKrishna Gudipati 
6567a36c61f9SKrishna Gudipati 
65685fbe25c7SJing Huang /*
6569a36c61f9SKrishna Gudipati  *     This routine will be called by bfa_timer on timer timeouts.
6570a36c61f9SKrishna Gudipati  *
6571a36c61f9SKrishna Gudipati  *	param[in]	vport		- pointer to bfa_fcs_vport_t.
6572a36c61f9SKrishna Gudipati  *	param[out]	vport_status	- pointer to return vport status in
6573a36c61f9SKrishna Gudipati  *
6574a36c61f9SKrishna Gudipati  *	return
6575a36c61f9SKrishna Gudipati  *		void
6576a36c61f9SKrishna Gudipati  *
6577a36c61f9SKrishna Gudipati  *	Special Considerations:
6578a36c61f9SKrishna Gudipati  *
6579a36c61f9SKrishna Gudipati  *	note
6580a36c61f9SKrishna Gudipati  */
6581a36c61f9SKrishna Gudipati static void
6582a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout(void *vport_arg)
6583a36c61f9SKrishna Gudipati {
6584a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg;
6585a36c61f9SKrishna Gudipati 
6586a36c61f9SKrishna Gudipati 	vport->vport_stats.fdisc_timeouts++;
6587a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT);
6588a36c61f9SKrishna Gudipati }
6589a36c61f9SKrishna Gudipati 
6590a36c61f9SKrishna Gudipati static void
6591a36c61f9SKrishna Gudipati bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
6592a36c61f9SKrishna Gudipati {
6593a36c61f9SKrishna Gudipati 	struct bfad_vport_s *vport_drv =
6594a36c61f9SKrishna Gudipati 			(struct bfad_vport_s *)vport->vport_drv;
6595a36c61f9SKrishna Gudipati 
6596a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
6597a36c61f9SKrishna Gudipati 	bfa_lps_delete(vport->lps);
659817c201b3SKrishna Gudipati 
659917c201b3SKrishna Gudipati 	if (vport_drv->comp_del) {
660017c201b3SKrishna Gudipati 		complete(vport_drv->comp_del);
660117c201b3SKrishna Gudipati 		return;
6602a36c61f9SKrishna Gudipati 	}
6603a36c61f9SKrishna Gudipati 
660417c201b3SKrishna Gudipati 	/*
660517c201b3SKrishna Gudipati 	 * We queue the vport delete work to the IM work_q from here.
660617c201b3SKrishna Gudipati 	 * The memory for the bfad_vport_s is freed from the FC function
660717c201b3SKrishna Gudipati 	 * template vport_delete entry point.
660817c201b3SKrishna Gudipati 	 */
6609529f9a76SKrishna Gudipati 	bfad_im_port_delete(vport_drv->drv_port.bfad, &vport_drv->drv_port);
661017c201b3SKrishna Gudipati }
6611a36c61f9SKrishna Gudipati 
66125fbe25c7SJing Huang /*
6613a36c61f9SKrishna Gudipati  *  fcs_vport_public FCS virtual port public interfaces
6614a36c61f9SKrishna Gudipati  */
6615a36c61f9SKrishna Gudipati 
66165fbe25c7SJing Huang /*
6617a36c61f9SKrishna Gudipati  * Online notification from fabric SM.
6618a36c61f9SKrishna Gudipati  */
6619a36c61f9SKrishna Gudipati void
6620a36c61f9SKrishna Gudipati bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport)
6621a36c61f9SKrishna Gudipati {
6622a36c61f9SKrishna Gudipati 	vport->vport_stats.fab_online++;
6623d7be54ccSKrishna Gudipati 	if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport)))
6624a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
6625d7be54ccSKrishna Gudipati 	else
6626d7be54ccSKrishna Gudipati 		vport->vport_stats.fab_no_npiv++;
6627a36c61f9SKrishna Gudipati }
6628a36c61f9SKrishna Gudipati 
66295fbe25c7SJing Huang /*
6630a36c61f9SKrishna Gudipati  * Offline notification from fabric SM.
6631a36c61f9SKrishna Gudipati  */
6632a36c61f9SKrishna Gudipati void
6633a36c61f9SKrishna Gudipati bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport)
6634a36c61f9SKrishna Gudipati {
6635a36c61f9SKrishna Gudipati 	vport->vport_stats.fab_offline++;
6636a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
6637a36c61f9SKrishna Gudipati }
6638a36c61f9SKrishna Gudipati 
66395fbe25c7SJing Huang /*
6640a36c61f9SKrishna Gudipati  * Cleanup notification from fabric SM on link timer expiry.
6641a36c61f9SKrishna Gudipati  */
6642a36c61f9SKrishna Gudipati void
6643a36c61f9SKrishna Gudipati bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
6644a36c61f9SKrishna Gudipati {
6645a36c61f9SKrishna Gudipati 	vport->vport_stats.fab_cleanup++;
6646a36c61f9SKrishna Gudipati }
6647881c1b3cSKrishna Gudipati 
6648881c1b3cSKrishna Gudipati /*
6649881c1b3cSKrishna Gudipati  * Stop notification from fabric SM. To be invoked from within FCS.
6650881c1b3cSKrishna Gudipati  */
6651881c1b3cSKrishna Gudipati void
6652881c1b3cSKrishna Gudipati bfa_fcs_vport_fcs_stop(struct bfa_fcs_vport_s *vport)
6653881c1b3cSKrishna Gudipati {
6654881c1b3cSKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
6655881c1b3cSKrishna Gudipati }
6656881c1b3cSKrishna Gudipati 
66575fbe25c7SJing Huang /*
6658a36c61f9SKrishna Gudipati  * delete notification from fabric SM. To be invoked from within FCS.
6659a36c61f9SKrishna Gudipati  */
6660a36c61f9SKrishna Gudipati void
6661a36c61f9SKrishna Gudipati bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport)
6662a36c61f9SKrishna Gudipati {
6663a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
6664a36c61f9SKrishna Gudipati }
6665a36c61f9SKrishna Gudipati 
66665fbe25c7SJing Huang /*
6667dd5aaf45SKrishna Gudipati  * Stop completion callback from associated lport
6668dd5aaf45SKrishna Gudipati  */
6669dd5aaf45SKrishna Gudipati void
6670dd5aaf45SKrishna Gudipati bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport)
6671dd5aaf45SKrishna Gudipati {
6672dd5aaf45SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP);
6673dd5aaf45SKrishna Gudipati }
6674dd5aaf45SKrishna Gudipati 
6675dd5aaf45SKrishna Gudipati /*
6676a36c61f9SKrishna Gudipati  * Delete completion callback from associated lport
6677a36c61f9SKrishna Gudipati  */
6678a36c61f9SKrishna Gudipati void
6679a36c61f9SKrishna Gudipati bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
6680a36c61f9SKrishna Gudipati {
6681a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP);
6682a36c61f9SKrishna Gudipati }
6683a36c61f9SKrishna Gudipati 
6684a36c61f9SKrishna Gudipati 
6685a36c61f9SKrishna Gudipati 
66865fbe25c7SJing Huang /*
6687a36c61f9SKrishna Gudipati  *  fcs_vport_api Virtual port API
6688a36c61f9SKrishna Gudipati  */
6689a36c61f9SKrishna Gudipati 
66905fbe25c7SJing Huang /*
6691a36c61f9SKrishna Gudipati  *	Use this function to instantiate a new FCS vport object. This
6692a36c61f9SKrishna Gudipati  *	function will not trigger any HW initialization process (which will be
6693a36c61f9SKrishna Gudipati  *	done in vport_start() call)
6694a36c61f9SKrishna Gudipati  *
6695a36c61f9SKrishna Gudipati  *	param[in] vport	-		pointer to bfa_fcs_vport_t. This space
6696a36c61f9SKrishna Gudipati  *					needs to be allocated by the driver.
6697a36c61f9SKrishna Gudipati  *	param[in] fcs		-	FCS instance
6698a36c61f9SKrishna Gudipati  *	param[in] vport_cfg	-	vport configuration
6699a36c61f9SKrishna Gudipati  *	param[in] vf_id		-	VF_ID if vport is created within a VF.
6700a36c61f9SKrishna Gudipati  *					FC_VF_ID_NULL to specify base fabric.
6701a36c61f9SKrishna Gudipati  *	param[in] vport_drv	-	Opaque handle back to the driver's vport
6702a36c61f9SKrishna Gudipati  *					structure
6703a36c61f9SKrishna Gudipati  *
6704a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_OK - on success.
6705a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_FAILED - on failure.
6706a36c61f9SKrishna Gudipati  */
6707a36c61f9SKrishna Gudipati bfa_status_t
6708a36c61f9SKrishna Gudipati bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
6709a36c61f9SKrishna Gudipati 		u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
6710a36c61f9SKrishna Gudipati 		struct bfad_vport_s *vport_drv)
6711a36c61f9SKrishna Gudipati {
6712a36c61f9SKrishna Gudipati 	if (vport_cfg->pwwn == 0)
6713a36c61f9SKrishna Gudipati 		return BFA_STATUS_INVALID_WWN;
6714a36c61f9SKrishna Gudipati 
6715a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
6716a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_WWN_BP;
6717a36c61f9SKrishna Gudipati 
6718a36c61f9SKrishna Gudipati 	if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
6719a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_EXISTS;
6720a36c61f9SKrishna Gudipati 
6721f7f73812SMaggie Zhang 	if (fcs->fabric.num_vports ==
6722a36c61f9SKrishna Gudipati 			bfa_lps_get_max_vport(fcs->bfa))
6723a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_MAX;
6724a36c61f9SKrishna Gudipati 
6725a36c61f9SKrishna Gudipati 	vport->lps = bfa_lps_alloc(fcs->bfa);
6726a36c61f9SKrishna Gudipati 	if (!vport->lps)
6727a36c61f9SKrishna Gudipati 		return BFA_STATUS_VPORT_MAX;
6728a36c61f9SKrishna Gudipati 
6729a36c61f9SKrishna Gudipati 	vport->vport_drv = vport_drv;
6730a36c61f9SKrishna Gudipati 	vport_cfg->preboot_vp = BFA_FALSE;
6731a36c61f9SKrishna Gudipati 
6732a36c61f9SKrishna Gudipati 	bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
6733a36c61f9SKrishna Gudipati 	bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
6734a36c61f9SKrishna Gudipati 	bfa_fcs_lport_init(&vport->lport, vport_cfg);
6735a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
6736a36c61f9SKrishna Gudipati 
6737a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
6738a36c61f9SKrishna Gudipati }
6739a36c61f9SKrishna Gudipati 
67405fbe25c7SJing Huang /*
6741a36c61f9SKrishna Gudipati  *	Use this function to instantiate a new FCS PBC vport object. This
6742a36c61f9SKrishna Gudipati  *	function will not trigger any HW initialization process (which will be
6743a36c61f9SKrishna Gudipati  *	done in vport_start() call)
6744a36c61f9SKrishna Gudipati  *
6745a36c61f9SKrishna Gudipati  *	param[in] vport	-	pointer to bfa_fcs_vport_t. This space
6746a36c61f9SKrishna Gudipati  *				needs to be allocated by the driver.
6747a36c61f9SKrishna Gudipati  *	param[in] fcs	-	FCS instance
6748a36c61f9SKrishna Gudipati  *	param[in] vport_cfg	-	vport configuration
6749a36c61f9SKrishna Gudipati  *	param[in] vf_id		-	VF_ID if vport is created within a VF.
6750a36c61f9SKrishna Gudipati  *					FC_VF_ID_NULL to specify base fabric.
6751a36c61f9SKrishna Gudipati  *	param[in] vport_drv	-	Opaque handle back to the driver's vport
6752a36c61f9SKrishna Gudipati  *					structure
6753a36c61f9SKrishna Gudipati  *
6754a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_OK - on success.
6755a36c61f9SKrishna Gudipati  *	retval BFA_STATUS_FAILED - on failure.
6756a36c61f9SKrishna Gudipati  */
6757a36c61f9SKrishna Gudipati bfa_status_t
6758a36c61f9SKrishna Gudipati bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
6759a36c61f9SKrishna Gudipati 			u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
6760a36c61f9SKrishna Gudipati 			struct bfad_vport_s *vport_drv)
6761a36c61f9SKrishna Gudipati {
6762a36c61f9SKrishna Gudipati 	bfa_status_t rc;
6763a36c61f9SKrishna Gudipati 
6764a36c61f9SKrishna Gudipati 	rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv);
6765a36c61f9SKrishna Gudipati 	vport->lport.port_cfg.preboot_vp = BFA_TRUE;
6766a36c61f9SKrishna Gudipati 
6767a36c61f9SKrishna Gudipati 	return rc;
6768a36c61f9SKrishna Gudipati }
6769a36c61f9SKrishna Gudipati 
67705fbe25c7SJing Huang /*
6771a36c61f9SKrishna Gudipati  *	Use this function to findout if this is a pbc vport or not.
6772a36c61f9SKrishna Gudipati  *
6773a36c61f9SKrishna Gudipati  * @param[in] vport - pointer to bfa_fcs_vport_t.
6774a36c61f9SKrishna Gudipati  *
6775a36c61f9SKrishna Gudipati  * @returns None
6776a36c61f9SKrishna Gudipati  */
6777a36c61f9SKrishna Gudipati bfa_boolean_t
6778a36c61f9SKrishna Gudipati bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport)
6779a36c61f9SKrishna Gudipati {
6780a36c61f9SKrishna Gudipati 
6781a36c61f9SKrishna Gudipati 	if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE))
6782a36c61f9SKrishna Gudipati 		return BFA_TRUE;
6783a36c61f9SKrishna Gudipati 	else
6784a36c61f9SKrishna Gudipati 		return BFA_FALSE;
6785a36c61f9SKrishna Gudipati 
6786a36c61f9SKrishna Gudipati }
6787a36c61f9SKrishna Gudipati 
67885fbe25c7SJing Huang /*
6789a36c61f9SKrishna Gudipati  * Use this function initialize the vport.
6790a36c61f9SKrishna Gudipati  *
6791a36c61f9SKrishna Gudipati  * @param[in] vport - pointer to bfa_fcs_vport_t.
6792a36c61f9SKrishna Gudipati  *
6793a36c61f9SKrishna Gudipati  * @returns None
6794a36c61f9SKrishna Gudipati  */
6795a36c61f9SKrishna Gudipati bfa_status_t
6796a36c61f9SKrishna Gudipati bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport)
6797a36c61f9SKrishna Gudipati {
6798a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START);
6799a36c61f9SKrishna Gudipati 
6800a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
6801a36c61f9SKrishna Gudipati }
6802a36c61f9SKrishna Gudipati 
68035fbe25c7SJing Huang /*
6804a36c61f9SKrishna Gudipati  *	Use this function quiese the vport object. This function will return
6805a36c61f9SKrishna Gudipati  *	immediately, when the vport is actually stopped, the
6806a36c61f9SKrishna Gudipati  *	bfa_drv_vport_stop_cb() will be called.
6807a36c61f9SKrishna Gudipati  *
6808a36c61f9SKrishna Gudipati  *	param[in] vport - pointer to bfa_fcs_vport_t.
6809a36c61f9SKrishna Gudipati  *
6810a36c61f9SKrishna Gudipati  *	return None
6811a36c61f9SKrishna Gudipati  */
6812a36c61f9SKrishna Gudipati bfa_status_t
6813a36c61f9SKrishna Gudipati bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
6814a36c61f9SKrishna Gudipati {
6815a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
6816a36c61f9SKrishna Gudipati 
6817a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
6818a36c61f9SKrishna Gudipati }
6819a36c61f9SKrishna Gudipati 
68205fbe25c7SJing Huang /*
6821a36c61f9SKrishna Gudipati  *	Use this function to delete a vport object. Fabric object should
6822a36c61f9SKrishna Gudipati  *	be stopped before this function call.
6823a36c61f9SKrishna Gudipati  *
6824a36c61f9SKrishna Gudipati  *	!!!!!!! Donot invoke this from within FCS  !!!!!!!
6825a36c61f9SKrishna Gudipati  *
6826a36c61f9SKrishna Gudipati  *	param[in] vport - pointer to bfa_fcs_vport_t.
6827a36c61f9SKrishna Gudipati  *
6828a36c61f9SKrishna Gudipati  *	return     None
6829a36c61f9SKrishna Gudipati  */
6830a36c61f9SKrishna Gudipati bfa_status_t
6831a36c61f9SKrishna Gudipati bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport)
6832a36c61f9SKrishna Gudipati {
6833a36c61f9SKrishna Gudipati 
6834a36c61f9SKrishna Gudipati 	if (vport->lport.port_cfg.preboot_vp)
6835a36c61f9SKrishna Gudipati 		return BFA_STATUS_PBC;
6836a36c61f9SKrishna Gudipati 
6837a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
6838a36c61f9SKrishna Gudipati 
6839a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
6840a36c61f9SKrishna Gudipati }
6841a36c61f9SKrishna Gudipati 
68425fbe25c7SJing Huang /*
6843a36c61f9SKrishna Gudipati  *	Use this function to get vport's current status info.
6844a36c61f9SKrishna Gudipati  *
6845a36c61f9SKrishna Gudipati  *	param[in] vport		pointer to bfa_fcs_vport_t.
6846a36c61f9SKrishna Gudipati  *	param[out] attr		pointer to return vport attributes
6847a36c61f9SKrishna Gudipati  *
6848a36c61f9SKrishna Gudipati  *	return None
6849a36c61f9SKrishna Gudipati  */
6850a36c61f9SKrishna Gudipati void
6851a36c61f9SKrishna Gudipati bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
6852a36c61f9SKrishna Gudipati 			struct bfa_vport_attr_s *attr)
6853a36c61f9SKrishna Gudipati {
6854a36c61f9SKrishna Gudipati 	if (vport == NULL || attr == NULL)
6855a36c61f9SKrishna Gudipati 		return;
6856a36c61f9SKrishna Gudipati 
68576a18b167SJing Huang 	memset(attr, 0, sizeof(struct bfa_vport_attr_s));
6858a36c61f9SKrishna Gudipati 
6859a36c61f9SKrishna Gudipati 	bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr);
6860a36c61f9SKrishna Gudipati 	attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
6861a36c61f9SKrishna Gudipati }
6862a36c61f9SKrishna Gudipati 
6863a36c61f9SKrishna Gudipati 
68645fbe25c7SJing Huang /*
6865a36c61f9SKrishna Gudipati  *	Lookup a virtual port. Excludes base port from lookup.
6866a36c61f9SKrishna Gudipati  */
6867a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *
6868a36c61f9SKrishna Gudipati bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn)
6869a36c61f9SKrishna Gudipati {
6870a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
6871a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
6872a36c61f9SKrishna Gudipati 
6873a36c61f9SKrishna Gudipati 	bfa_trc(fcs, vf_id);
6874a36c61f9SKrishna Gudipati 	bfa_trc(fcs, vpwwn);
6875a36c61f9SKrishna Gudipati 
6876a36c61f9SKrishna Gudipati 	fabric = bfa_fcs_vf_lookup(fcs, vf_id);
6877a36c61f9SKrishna Gudipati 	if (!fabric) {
6878a36c61f9SKrishna Gudipati 		bfa_trc(fcs, vf_id);
6879a36c61f9SKrishna Gudipati 		return NULL;
6880a36c61f9SKrishna Gudipati 	}
6881a36c61f9SKrishna Gudipati 
6882a36c61f9SKrishna Gudipati 	vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn);
6883a36c61f9SKrishna Gudipati 	return vport;
6884a36c61f9SKrishna Gudipati }
6885a36c61f9SKrishna Gudipati 
68865fbe25c7SJing Huang /*
6887a36c61f9SKrishna Gudipati  * FDISC Response
6888a36c61f9SKrishna Gudipati  */
6889a36c61f9SKrishna Gudipati void
6890a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
6891a36c61f9SKrishna Gudipati {
6892a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = uarg;
6893a36c61f9SKrishna Gudipati 
6894a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6895a36c61f9SKrishna Gudipati 	bfa_trc(__vport_fcs(vport), status);
6896a36c61f9SKrishna Gudipati 
6897a36c61f9SKrishna Gudipati 	switch (status) {
6898a36c61f9SKrishna Gudipati 	case BFA_STATUS_OK:
6899a36c61f9SKrishna Gudipati 		/*
6900b595076aSUwe Kleine-König 		 * Initialize the V-Port fields
6901a36c61f9SKrishna Gudipati 		 */
6902f7f73812SMaggie Zhang 		__vport_fcid(vport) = vport->lps->lp_pid;
6903a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_accepts++;
6904a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
6905a36c61f9SKrishna Gudipati 		break;
6906a36c61f9SKrishna Gudipati 
6907a36c61f9SKrishna Gudipati 	case BFA_STATUS_INVALID_MAC:
6908a36c61f9SKrishna Gudipati 		/* Only for CNA */
6909a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_acc_bad++;
6910a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6911a36c61f9SKrishna Gudipati 
6912a36c61f9SKrishna Gudipati 		break;
6913a36c61f9SKrishna Gudipati 
6914a36c61f9SKrishna Gudipati 	case BFA_STATUS_EPROTOCOL:
6915f7f73812SMaggie Zhang 		switch (vport->lps->ext_status) {
6916a36c61f9SKrishna Gudipati 		case BFA_EPROTO_BAD_ACCEPT:
6917a36c61f9SKrishna Gudipati 			vport->vport_stats.fdisc_acc_bad++;
6918a36c61f9SKrishna Gudipati 			break;
6919a36c61f9SKrishna Gudipati 
6920a36c61f9SKrishna Gudipati 		case BFA_EPROTO_UNKNOWN_RSP:
6921a36c61f9SKrishna Gudipati 			vport->vport_stats.fdisc_unknown_rsp++;
6922a36c61f9SKrishna Gudipati 			break;
6923a36c61f9SKrishna Gudipati 
6924a36c61f9SKrishna Gudipati 		default:
6925a36c61f9SKrishna Gudipati 			break;
6926a36c61f9SKrishna Gudipati 		}
6927a36c61f9SKrishna Gudipati 
6928f2a0cc3fSVijaya Mohan Guvva 		if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
6929a36c61f9SKrishna Gudipati 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6930f2a0cc3fSVijaya Mohan Guvva 		else
6931f2a0cc3fSVijaya Mohan Guvva 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
6932f2a0cc3fSVijaya Mohan Guvva 
6933f2a0cc3fSVijaya Mohan Guvva 		break;
6934f2a0cc3fSVijaya Mohan Guvva 
6935f2a0cc3fSVijaya Mohan Guvva 	case BFA_STATUS_ETIMER:
6936f2a0cc3fSVijaya Mohan Guvva 		vport->vport_stats.fdisc_timeouts++;
6937f2a0cc3fSVijaya Mohan Guvva 		if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
6938f2a0cc3fSVijaya Mohan Guvva 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6939f2a0cc3fSVijaya Mohan Guvva 		else
6940f2a0cc3fSVijaya Mohan Guvva 			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
6941a36c61f9SKrishna Gudipati 		break;
6942a36c61f9SKrishna Gudipati 
6943a36c61f9SKrishna Gudipati 	case BFA_STATUS_FABRIC_RJT:
6944a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_rejects++;
6945a36c61f9SKrishna Gudipati 		bfa_fcs_vport_fdisc_rejected(vport);
6946a36c61f9SKrishna Gudipati 		break;
6947a36c61f9SKrishna Gudipati 
6948a36c61f9SKrishna Gudipati 	default:
6949a36c61f9SKrishna Gudipati 		vport->vport_stats.fdisc_rsp_err++;
6950a36c61f9SKrishna Gudipati 		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6951a36c61f9SKrishna Gudipati 	}
6952a36c61f9SKrishna Gudipati }
6953a36c61f9SKrishna Gudipati 
69545fbe25c7SJing Huang /*
6955a36c61f9SKrishna Gudipati  * LOGO response
6956a36c61f9SKrishna Gudipati  */
6957a36c61f9SKrishna Gudipati void
6958a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
6959a36c61f9SKrishna Gudipati {
6960a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = uarg;
6961a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
6962a36c61f9SKrishna Gudipati }
6963a36c61f9SKrishna Gudipati 
69645fbe25c7SJing Huang /*
6965a36c61f9SKrishna Gudipati  * Received clear virtual link
6966a36c61f9SKrishna Gudipati  */
6967a36c61f9SKrishna Gudipati void
6968a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(void *bfad, void *uarg)
6969a36c61f9SKrishna Gudipati {
6970a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport = uarg;
6971a36c61f9SKrishna Gudipati 
6972a36c61f9SKrishna Gudipati 	/* Send an Offline followed by an ONLINE */
6973a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
6974a36c61f9SKrishna Gudipati 	bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
6975a36c61f9SKrishna Gudipati }
6976