xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs.c (revision 889d0d42)
17725ccfdSJing Huang /*
2889d0d42SAnil Gurumurthy  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
3889d0d42SAnil Gurumurthy  * Copyright (c) 2014- QLogic Corporation.
47725ccfdSJing Huang  * All rights reserved
5889d0d42SAnil Gurumurthy  * www.qlogic.com
67725ccfdSJing Huang  *
77725ccfdSJing Huang  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
87725ccfdSJing Huang  *
97725ccfdSJing Huang  * This program is free software; you can redistribute it and/or modify it
107725ccfdSJing Huang  * under the terms of the GNU General Public License (GPL) Version 2 as
117725ccfdSJing Huang  * published by the Free Software Foundation
127725ccfdSJing Huang  *
137725ccfdSJing Huang  * This program is distributed in the hope that it will be useful, but
147725ccfdSJing Huang  * WITHOUT ANY WARRANTY; without even the implied warranty of
157725ccfdSJing Huang  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
167725ccfdSJing Huang  * General Public License for more details.
177725ccfdSJing Huang  */
187725ccfdSJing Huang 
195fbe25c7SJing Huang /*
207725ccfdSJing Huang  *  bfa_fcs.c BFA FCS main
217725ccfdSJing Huang  */
227725ccfdSJing Huang 
23f16a1750SMaggie Zhang #include "bfad_drv.h"
247826f304SKrishna Gudipati #include "bfad_im.h"
25a36c61f9SKrishna Gudipati #include "bfa_fcs.h"
26a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h"
27a36c61f9SKrishna Gudipati 
28a36c61f9SKrishna Gudipati BFA_TRC_FILE(FCS, FCS);
297725ccfdSJing Huang 
305fbe25c7SJing Huang /*
317725ccfdSJing Huang  * FCS sub-modules
327725ccfdSJing Huang  */
337725ccfdSJing Huang struct bfa_fcs_mod_s {
3482794a2eSKrishna Gudipati 	void		(*attach) (struct bfa_fcs_s *fcs);
357725ccfdSJing Huang 	void		(*modinit) (struct bfa_fcs_s *fcs);
367725ccfdSJing Huang 	void		(*modexit) (struct bfa_fcs_s *fcs);
377725ccfdSJing Huang };
387725ccfdSJing Huang 
397725ccfdSJing Huang #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
407725ccfdSJing Huang 
417725ccfdSJing Huang static struct bfa_fcs_mod_s fcs_modules[] = {
42a36c61f9SKrishna Gudipati 	{ bfa_fcs_port_attach, NULL, NULL },
4382794a2eSKrishna Gudipati 	{ bfa_fcs_uf_attach, NULL, NULL },
4482794a2eSKrishna Gudipati 	{ bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
4582794a2eSKrishna Gudipati 	  bfa_fcs_fabric_modexit },
467725ccfdSJing Huang };
477725ccfdSJing Huang 
485fbe25c7SJing Huang /*
497725ccfdSJing Huang  *  fcs_api BFA FCS API
507725ccfdSJing Huang  */
517725ccfdSJing Huang 
527725ccfdSJing Huang static void
537725ccfdSJing Huang bfa_fcs_exit_comp(void *fcs_cbarg)
547725ccfdSJing Huang {
557725ccfdSJing Huang 	struct bfa_fcs_s      *fcs = fcs_cbarg;
567725ccfdSJing Huang 	struct bfad_s         *bfad = fcs->bfad;
577725ccfdSJing Huang 
587725ccfdSJing Huang 	complete(&bfad->comp);
597725ccfdSJing Huang }
607725ccfdSJing Huang 
617725ccfdSJing Huang 
627725ccfdSJing Huang 
635fbe25c7SJing Huang /*
647725ccfdSJing Huang  *  fcs_api BFA FCS API
657725ccfdSJing Huang  */
667725ccfdSJing Huang 
675fbe25c7SJing Huang /*
6882794a2eSKrishna Gudipati  * fcs attach -- called once to initialize data structures at driver attach time
697725ccfdSJing Huang  */
707725ccfdSJing Huang void
7182794a2eSKrishna Gudipati bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
727725ccfdSJing Huang 	       bfa_boolean_t min_cfg)
737725ccfdSJing Huang {
747725ccfdSJing Huang 	int		i;
757725ccfdSJing Huang 	struct bfa_fcs_mod_s  *mod;
767725ccfdSJing Huang 
777725ccfdSJing Huang 	fcs->bfa = bfa;
787725ccfdSJing Huang 	fcs->bfad = bfad;
797725ccfdSJing Huang 	fcs->min_cfg = min_cfg;
8061ba4394SKrishna Gudipati 	fcs->num_rport_logins = 0;
817725ccfdSJing Huang 
82f7f73812SMaggie Zhang 	bfa->fcs = BFA_TRUE;
837725ccfdSJing Huang 	fcbuild_init();
847725ccfdSJing Huang 
8544416c42SFabian Frederick 	for (i = 0; i < ARRAY_SIZE(fcs_modules); i++) {
867725ccfdSJing Huang 		mod = &fcs_modules[i];
8782794a2eSKrishna Gudipati 		if (mod->attach)
8882794a2eSKrishna Gudipati 			mod->attach(fcs);
8982794a2eSKrishna Gudipati 	}
9082794a2eSKrishna Gudipati }
9182794a2eSKrishna Gudipati 
925fbe25c7SJing Huang /*
9382794a2eSKrishna Gudipati  * fcs initialization, called once after bfa initialization is complete
9482794a2eSKrishna Gudipati  */
9582794a2eSKrishna Gudipati void
9682794a2eSKrishna Gudipati bfa_fcs_init(struct bfa_fcs_s *fcs)
9782794a2eSKrishna Gudipati {
9875332a70SKrishna Gudipati 	int	i;
9982794a2eSKrishna Gudipati 	struct bfa_fcs_mod_s  *mod;
10082794a2eSKrishna Gudipati 
10144416c42SFabian Frederick 	for (i = 0; i < ARRAY_SIZE(fcs_modules); i++) {
10282794a2eSKrishna Gudipati 		mod = &fcs_modules[i];
10382794a2eSKrishna Gudipati 		if (mod->modinit)
1047725ccfdSJing Huang 			mod->modinit(fcs);
1057725ccfdSJing Huang 	}
10675332a70SKrishna Gudipati }
10775332a70SKrishna Gudipati 
10875332a70SKrishna Gudipati /*
10975332a70SKrishna Gudipati  * FCS update cfg - reset the pwwn/nwwn of fabric base logical port
11075332a70SKrishna Gudipati  * with values learned during bfa_init firmware GETATTR REQ.
11175332a70SKrishna Gudipati  */
11275332a70SKrishna Gudipati void
11375332a70SKrishna Gudipati bfa_fcs_update_cfg(struct bfa_fcs_s *fcs)
11475332a70SKrishna Gudipati {
11575332a70SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = &fcs->fabric;
11675332a70SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
11775332a70SKrishna Gudipati 	struct bfa_ioc_s *ioc = &fabric->fcs->bfa->ioc;
11875332a70SKrishna Gudipati 
11975332a70SKrishna Gudipati 	port_cfg->nwwn = ioc->attr->nwwn;
12075332a70SKrishna Gudipati 	port_cfg->pwwn = ioc->attr->pwwn;
12175332a70SKrishna Gudipati }
12275332a70SKrishna Gudipati 
12375332a70SKrishna Gudipati /*
124881c1b3cSKrishna Gudipati  * Stop FCS operations.
125881c1b3cSKrishna Gudipati  */
126881c1b3cSKrishna Gudipati void
127881c1b3cSKrishna Gudipati bfa_fcs_stop(struct bfa_fcs_s *fcs)
128881c1b3cSKrishna Gudipati {
129881c1b3cSKrishna Gudipati 	bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
130881c1b3cSKrishna Gudipati 	bfa_wc_up(&fcs->wc);
131881c1b3cSKrishna Gudipati 	bfa_fcs_fabric_modstop(fcs);
132881c1b3cSKrishna Gudipati 	bfa_wc_wait(&fcs->wc);
133881c1b3cSKrishna Gudipati }
134881c1b3cSKrishna Gudipati 
135881c1b3cSKrishna Gudipati /*
13675332a70SKrishna Gudipati  * fcs pbc vport initialization
13775332a70SKrishna Gudipati  */
13875332a70SKrishna Gudipati void
13975332a70SKrishna Gudipati bfa_fcs_pbc_vport_init(struct bfa_fcs_s *fcs)
14075332a70SKrishna Gudipati {
14175332a70SKrishna Gudipati 	int i, npbc_vports;
14275332a70SKrishna Gudipati 	struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];
14375332a70SKrishna Gudipati 
144d9883548SJing Huang 	/* Initialize pbc vports */
145d9883548SJing Huang 	if (!fcs->min_cfg) {
146d9883548SJing Huang 		npbc_vports =
147d9883548SJing Huang 			bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
148d9883548SJing Huang 		for (i = 0; i < npbc_vports; i++)
149d9883548SJing Huang 			bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
150d9883548SJing Huang 	}
1517725ccfdSJing Huang }
1527725ccfdSJing Huang 
1535fbe25c7SJing Huang /*
154a36c61f9SKrishna Gudipati  *	brief
1557725ccfdSJing Huang  *		FCS driver details initialization.
1567725ccfdSJing Huang  *
1577725ccfdSJing Huang  *	param[in]		fcs		FCS instance
1587725ccfdSJing Huang  *	param[in]		driver_info	Driver Details
1597725ccfdSJing Huang  *
1607725ccfdSJing Huang  *	return None
1617725ccfdSJing Huang  */
1627725ccfdSJing Huang void
1637725ccfdSJing Huang bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
1647725ccfdSJing Huang 			struct bfa_fcs_driver_info_s *driver_info)
1657725ccfdSJing Huang {
1667725ccfdSJing Huang 
1677725ccfdSJing Huang 	fcs->driver_info = *driver_info;
1687725ccfdSJing Huang 
1697725ccfdSJing Huang 	bfa_fcs_fabric_psymb_init(&fcs->fabric);
170ce7242b8SKrishna Gudipati 	bfa_fcs_fabric_nsymb_init(&fcs->fabric);
1717725ccfdSJing Huang }
1727725ccfdSJing Huang 
1735fbe25c7SJing Huang /*
174a36c61f9SKrishna Gudipati  *	brief
1757725ccfdSJing Huang  *		FCS instance cleanup and exit.
1767725ccfdSJing Huang  *
1777725ccfdSJing Huang  *	param[in]		fcs			FCS instance
1787725ccfdSJing Huang  *	return None
1797725ccfdSJing Huang  */
1807725ccfdSJing Huang void
1817725ccfdSJing Huang bfa_fcs_exit(struct bfa_fcs_s *fcs)
1827725ccfdSJing Huang {
1837725ccfdSJing Huang 	struct bfa_fcs_mod_s  *mod;
184a36c61f9SKrishna Gudipati 	int		nmods, i;
1857725ccfdSJing Huang 
1867725ccfdSJing Huang 	bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
1877725ccfdSJing Huang 
18844416c42SFabian Frederick 	nmods = ARRAY_SIZE(fcs_modules);
189a36c61f9SKrishna Gudipati 
190a36c61f9SKrishna Gudipati 	for (i = 0; i < nmods; i++) {
1917725ccfdSJing Huang 
1927725ccfdSJing Huang 		mod = &fcs_modules[i];
19382794a2eSKrishna Gudipati 		if (mod->modexit) {
19482794a2eSKrishna Gudipati 			bfa_wc_up(&fcs->wc);
1957725ccfdSJing Huang 			mod->modexit(fcs);
1967725ccfdSJing Huang 		}
19782794a2eSKrishna Gudipati 	}
1987725ccfdSJing Huang 
1997725ccfdSJing Huang 	bfa_wc_wait(&fcs->wc);
2007725ccfdSJing Huang }
2017725ccfdSJing Huang 
2027725ccfdSJing Huang 
2035fbe25c7SJing Huang /*
204a36c61f9SKrishna Gudipati  * Fabric module implementation.
205a36c61f9SKrishna Gudipati  */
2067725ccfdSJing Huang 
207a36c61f9SKrishna Gudipati #define BFA_FCS_FABRIC_RETRY_DELAY	(2000)	/* Milliseconds */
208a36c61f9SKrishna Gudipati #define BFA_FCS_FABRIC_CLEANUP_DELAY	(10000)	/* Milliseconds */
209a36c61f9SKrishna Gudipati 
210a36c61f9SKrishna Gudipati #define bfa_fcs_fabric_set_opertype(__fabric) do {			\
211a36c61f9SKrishna Gudipati 	if (bfa_fcport_get_topology((__fabric)->fcs->bfa)		\
212d7be54ccSKrishna Gudipati 				== BFA_PORT_TOPOLOGY_P2P) {		\
213d7be54ccSKrishna Gudipati 		if (fabric->fab_type == BFA_FCS_FABRIC_SWITCHED)	\
214a36c61f9SKrishna Gudipati 			(__fabric)->oper_type = BFA_PORT_TYPE_NPORT;	\
215a36c61f9SKrishna Gudipati 		else							\
216d7be54ccSKrishna Gudipati 			(__fabric)->oper_type = BFA_PORT_TYPE_P2P;	\
217d7be54ccSKrishna Gudipati 	} else								\
218a36c61f9SKrishna Gudipati 		(__fabric)->oper_type = BFA_PORT_TYPE_NLPORT;		\
219a36c61f9SKrishna Gudipati } while (0)
220a36c61f9SKrishna Gudipati 
221a36c61f9SKrishna Gudipati /*
222a36c61f9SKrishna Gudipati  * forward declarations
223a36c61f9SKrishna Gudipati  */
224a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
225a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
226a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
227a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
228a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delay(void *cbarg);
229a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
230a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delete_comp(void *cbarg);
231881c1b3cSKrishna Gudipati static void bfa_fcs_fabric_stop(struct bfa_fcs_fabric_s *fabric);
232881c1b3cSKrishna Gudipati static void bfa_fcs_fabric_stop_comp(void *cbarg);
233a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
234a36c61f9SKrishna Gudipati 				      struct fchs_s *fchs, u16 len);
235a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
236a36c61f9SKrishna Gudipati 					 struct fchs_s *fchs, u16 len);
237a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
238a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
239a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp, void *cbarg,
240a36c61f9SKrishna Gudipati 					 bfa_status_t status,
241a36c61f9SKrishna Gudipati 					 u32 rsp_len,
242a36c61f9SKrishna Gudipati 					 u32 resid_len,
243a36c61f9SKrishna Gudipati 					 struct fchs_s *rspfchs);
244a36c61f9SKrishna Gudipati 
245a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
246a36c61f9SKrishna Gudipati 					 enum bfa_fcs_fabric_event event);
247a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
248a36c61f9SKrishna Gudipati 					  enum bfa_fcs_fabric_event event);
249a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
250a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
251a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
252a36c61f9SKrishna Gudipati 					enum bfa_fcs_fabric_event event);
253a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
254a36c61f9SKrishna Gudipati 					      enum bfa_fcs_fabric_event event);
255a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
256a36c61f9SKrishna Gudipati 				       enum bfa_fcs_fabric_event event);
257a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
258a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
259a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
260a36c61f9SKrishna Gudipati 				       enum bfa_fcs_fabric_event event);
261a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
262a36c61f9SKrishna Gudipati 					    enum bfa_fcs_fabric_event event);
263a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
264a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
265a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
266a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
267881c1b3cSKrishna Gudipati static void	bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric,
268881c1b3cSKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
269881c1b3cSKrishna Gudipati static void	bfa_fcs_fabric_sm_cleanup(struct bfa_fcs_fabric_s *fabric,
270881c1b3cSKrishna Gudipati 					  enum bfa_fcs_fabric_event event);
2715fbe25c7SJing Huang /*
272a36c61f9SKrishna Gudipati  *   Beginning state before fabric creation.
273a36c61f9SKrishna Gudipati  */
274a36c61f9SKrishna Gudipati static void
275a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
276a36c61f9SKrishna Gudipati 			 enum bfa_fcs_fabric_event event)
277a36c61f9SKrishna Gudipati {
278a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
279a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
280a36c61f9SKrishna Gudipati 
281a36c61f9SKrishna Gudipati 	switch (event) {
282a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CREATE:
283a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
284a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_init(fabric);
285a36c61f9SKrishna Gudipati 		bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
286a36c61f9SKrishna Gudipati 		break;
287a36c61f9SKrishna Gudipati 
288a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
289a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
290a36c61f9SKrishna Gudipati 		break;
291a36c61f9SKrishna Gudipati 
292a36c61f9SKrishna Gudipati 	default:
293a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
294a36c61f9SKrishna Gudipati 	}
295a36c61f9SKrishna Gudipati }
296a36c61f9SKrishna Gudipati 
2975fbe25c7SJing Huang /*
298a36c61f9SKrishna Gudipati  *   Beginning state before fabric creation.
299a36c61f9SKrishna Gudipati  */
300a36c61f9SKrishna Gudipati static void
301a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
302a36c61f9SKrishna Gudipati 			  enum bfa_fcs_fabric_event event)
303a36c61f9SKrishna Gudipati {
304bc0e2c2aSKrishna Gudipati 	struct bfa_s	*bfa = fabric->fcs->bfa;
305bc0e2c2aSKrishna Gudipati 
306a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
307a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
308a36c61f9SKrishna Gudipati 
309a36c61f9SKrishna Gudipati 	switch (event) {
310a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_START:
311bc0e2c2aSKrishna Gudipati 		if (!bfa_fcport_is_linkup(fabric->fcs->bfa)) {
312bc0e2c2aSKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
313bc0e2c2aSKrishna Gudipati 			break;
314bc0e2c2aSKrishna Gudipati 		}
315bc0e2c2aSKrishna Gudipati 		if (bfa_fcport_get_topology(bfa) ==
316bc0e2c2aSKrishna Gudipati 				BFA_PORT_TOPOLOGY_LOOP) {
317bc0e2c2aSKrishna Gudipati 			fabric->fab_type = BFA_FCS_FABRIC_LOOP;
318bc0e2c2aSKrishna Gudipati 			fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
319bc0e2c2aSKrishna Gudipati 			fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
320bc0e2c2aSKrishna Gudipati 			bfa_sm_set_state(fabric,
321bc0e2c2aSKrishna Gudipati 					bfa_fcs_fabric_sm_online);
322bc0e2c2aSKrishna Gudipati 			bfa_fcs_fabric_set_opertype(fabric);
323bc0e2c2aSKrishna Gudipati 			bfa_fcs_lport_online(&fabric->bport);
324bc0e2c2aSKrishna Gudipati 		} else {
325a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
326a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_login(fabric);
327bc0e2c2aSKrishna Gudipati 		}
328a36c61f9SKrishna Gudipati 		break;
329a36c61f9SKrishna Gudipati 
330a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
331a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
332a36c61f9SKrishna Gudipati 		break;
333a36c61f9SKrishna Gudipati 
334a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
335dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
336dd5aaf45SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
337a36c61f9SKrishna Gudipati 		break;
338a36c61f9SKrishna Gudipati 
339a36c61f9SKrishna Gudipati 	default:
340a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
341a36c61f9SKrishna Gudipati 	}
342a36c61f9SKrishna Gudipati }
343a36c61f9SKrishna Gudipati 
3445fbe25c7SJing Huang /*
345a36c61f9SKrishna Gudipati  *   Link is down, awaiting LINK UP event from port. This is also the
346a36c61f9SKrishna Gudipati  *   first state at fabric creation.
347a36c61f9SKrishna Gudipati  */
348a36c61f9SKrishna Gudipati static void
349a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
350a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
351a36c61f9SKrishna Gudipati {
352bc0e2c2aSKrishna Gudipati 	struct bfa_s	*bfa = fabric->fcs->bfa;
353bc0e2c2aSKrishna Gudipati 
354a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
355a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
356a36c61f9SKrishna Gudipati 
357a36c61f9SKrishna Gudipati 	switch (event) {
358a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
359bc0e2c2aSKrishna Gudipati 		if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) {
360a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
361a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_login(fabric);
362a36c61f9SKrishna Gudipati 			break;
363bc0e2c2aSKrishna Gudipati 		}
364bc0e2c2aSKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_LOOP;
365bc0e2c2aSKrishna Gudipati 		fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
366bc0e2c2aSKrishna Gudipati 		fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
367bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
368bc0e2c2aSKrishna Gudipati 		bfa_fcs_fabric_set_opertype(fabric);
369bc0e2c2aSKrishna Gudipati 		bfa_fcs_lport_online(&fabric->bport);
370bc0e2c2aSKrishna Gudipati 		break;
371a36c61f9SKrishna Gudipati 
372a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
373bc0e2c2aSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LOOPBACK:
374a36c61f9SKrishna Gudipati 		break;
375a36c61f9SKrishna Gudipati 
376a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
377a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
378a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
379a36c61f9SKrishna Gudipati 		break;
380a36c61f9SKrishna Gudipati 
381881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_STOP:
382881c1b3cSKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
383881c1b3cSKrishna Gudipati 		bfa_fcs_fabric_stop(fabric);
384881c1b3cSKrishna Gudipati 		break;
385881c1b3cSKrishna Gudipati 
386a36c61f9SKrishna Gudipati 	default:
387a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
388a36c61f9SKrishna Gudipati 	}
389a36c61f9SKrishna Gudipati }
390a36c61f9SKrishna Gudipati 
3915fbe25c7SJing Huang /*
392a36c61f9SKrishna Gudipati  *   FLOGI is in progress, awaiting FLOGI reply.
393a36c61f9SKrishna Gudipati  */
394a36c61f9SKrishna Gudipati static void
395a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
396a36c61f9SKrishna Gudipati 			enum bfa_fcs_fabric_event event)
397a36c61f9SKrishna Gudipati {
398a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
399a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
400a36c61f9SKrishna Gudipati 
401a36c61f9SKrishna Gudipati 	switch (event) {
402a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CONT_OP:
403a36c61f9SKrishna Gudipati 
404a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
405bbe37a67SVijaya Mohan Guvva 					   fabric->bb_credit);
406a36c61f9SKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
407a36c61f9SKrishna Gudipati 
408a36c61f9SKrishna Gudipati 		if (fabric->auth_reqd && fabric->is_auth) {
409a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth);
410a36c61f9SKrishna Gudipati 			bfa_trc(fabric->fcs, event);
411a36c61f9SKrishna Gudipati 		} else {
412a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
413a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_notify_online(fabric);
414a36c61f9SKrishna Gudipati 		}
415a36c61f9SKrishna Gudipati 		break;
416a36c61f9SKrishna Gudipati 
417a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
418a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry);
419a36c61f9SKrishna Gudipati 		bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer,
420a36c61f9SKrishna Gudipati 				bfa_fcs_fabric_delay, fabric,
421a36c61f9SKrishna Gudipati 				BFA_FCS_FABRIC_RETRY_DELAY);
422a36c61f9SKrishna Gudipati 		break;
423a36c61f9SKrishna Gudipati 
424a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LOOPBACK:
425a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
426f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
427a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_set_opertype(fabric);
428a36c61f9SKrishna Gudipati 		break;
429a36c61f9SKrishna Gudipati 
430a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
431a36c61f9SKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_N2N;
432a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
433bbe37a67SVijaya Mohan Guvva 					   fabric->bb_credit);
434a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_online(fabric);
435a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
436a36c61f9SKrishna Gudipati 		break;
437a36c61f9SKrishna Gudipati 
438a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
439a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
440f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
441a36c61f9SKrishna Gudipati 		break;
442a36c61f9SKrishna Gudipati 
443a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
444a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
445f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
446a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
447a36c61f9SKrishna Gudipati 		break;
448a36c61f9SKrishna Gudipati 
449a36c61f9SKrishna Gudipati 	default:
450a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
451a36c61f9SKrishna Gudipati 	}
452a36c61f9SKrishna Gudipati }
453a36c61f9SKrishna Gudipati 
454a36c61f9SKrishna Gudipati 
455a36c61f9SKrishna Gudipati static void
456a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
457a36c61f9SKrishna Gudipati 			      enum bfa_fcs_fabric_event event)
458a36c61f9SKrishna Gudipati {
459a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
460a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
461a36c61f9SKrishna Gudipati 
462a36c61f9SKrishna Gudipati 	switch (event) {
463a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELAYED:
464a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
465a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_login(fabric);
466a36c61f9SKrishna Gudipati 		break;
467a36c61f9SKrishna Gudipati 
468a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
469a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
470a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fabric->delay_timer);
471a36c61f9SKrishna Gudipati 		break;
472a36c61f9SKrishna Gudipati 
473a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
474a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
475a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fabric->delay_timer);
476a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
477a36c61f9SKrishna Gudipati 		break;
478a36c61f9SKrishna Gudipati 
479a36c61f9SKrishna Gudipati 	default:
480a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
481a36c61f9SKrishna Gudipati 	}
482a36c61f9SKrishna Gudipati }
483a36c61f9SKrishna Gudipati 
4845fbe25c7SJing Huang /*
485a36c61f9SKrishna Gudipati  *   Authentication is in progress, awaiting authentication results.
486a36c61f9SKrishna Gudipati  */
487a36c61f9SKrishna Gudipati static void
488a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
489a36c61f9SKrishna Gudipati 		       enum bfa_fcs_fabric_event event)
490a36c61f9SKrishna Gudipati {
491a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
492a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
493a36c61f9SKrishna Gudipati 
494a36c61f9SKrishna Gudipati 	switch (event) {
495a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_FAILED:
496a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
497f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
498a36c61f9SKrishna Gudipati 		break;
499a36c61f9SKrishna Gudipati 
500a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
501a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
502a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_online(fabric);
503a36c61f9SKrishna Gudipati 		break;
504a36c61f9SKrishna Gudipati 
505a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_PERF_EVFP:
506a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp);
507a36c61f9SKrishna Gudipati 		break;
508a36c61f9SKrishna Gudipati 
509a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
510a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
511f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
512a36c61f9SKrishna Gudipati 		break;
513a36c61f9SKrishna Gudipati 
514a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
515a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
516a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
517a36c61f9SKrishna Gudipati 		break;
518a36c61f9SKrishna Gudipati 
519a36c61f9SKrishna Gudipati 	default:
520a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
521a36c61f9SKrishna Gudipati 	}
522a36c61f9SKrishna Gudipati }
523a36c61f9SKrishna Gudipati 
5245fbe25c7SJing Huang /*
525a36c61f9SKrishna Gudipati  *   Authentication failed
526a36c61f9SKrishna Gudipati  */
527f7f73812SMaggie Zhang void
528a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
529a36c61f9SKrishna Gudipati 			      enum bfa_fcs_fabric_event event)
530a36c61f9SKrishna Gudipati {
531a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
532a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
533a36c61f9SKrishna Gudipati 
534a36c61f9SKrishna Gudipati 	switch (event) {
535a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
536a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
537a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
538a36c61f9SKrishna Gudipati 		break;
539a36c61f9SKrishna Gudipati 
540a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
541a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
542a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
543a36c61f9SKrishna Gudipati 		break;
544a36c61f9SKrishna Gudipati 
545a36c61f9SKrishna Gudipati 	default:
546a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
547a36c61f9SKrishna Gudipati 	}
548a36c61f9SKrishna Gudipati }
549a36c61f9SKrishna Gudipati 
5505fbe25c7SJing Huang /*
551a36c61f9SKrishna Gudipati  *   Port is in loopback mode.
552a36c61f9SKrishna Gudipati  */
553f7f73812SMaggie Zhang void
554a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
555a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
556a36c61f9SKrishna Gudipati {
557a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
558a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
559a36c61f9SKrishna Gudipati 
560a36c61f9SKrishna Gudipati 	switch (event) {
561a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
562a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
563a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
564a36c61f9SKrishna Gudipati 		break;
565a36c61f9SKrishna Gudipati 
566a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
567a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
568a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
569a36c61f9SKrishna Gudipati 		break;
570a36c61f9SKrishna Gudipati 
571a36c61f9SKrishna Gudipati 	default:
572a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
573a36c61f9SKrishna Gudipati 	}
574a36c61f9SKrishna Gudipati }
575a36c61f9SKrishna Gudipati 
5765fbe25c7SJing Huang /*
577a36c61f9SKrishna Gudipati  *   There is no attached fabric - private loop or NPort-to-NPort topology.
578a36c61f9SKrishna Gudipati  */
579a36c61f9SKrishna Gudipati static void
580a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
581a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
582a36c61f9SKrishna Gudipati {
583a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
584a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
585a36c61f9SKrishna Gudipati 
586a36c61f9SKrishna Gudipati 	switch (event) {
587a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
588a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
589f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
590a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
591a36c61f9SKrishna Gudipati 		break;
592a36c61f9SKrishna Gudipati 
593a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
594a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
595a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
596a36c61f9SKrishna Gudipati 		break;
597a36c61f9SKrishna Gudipati 
598a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
599a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, fabric->bb_credit);
600a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
601bbe37a67SVijaya Mohan Guvva 					   fabric->bb_credit);
602a36c61f9SKrishna Gudipati 		break;
603a36c61f9SKrishna Gudipati 
604d7be54ccSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
605d7be54ccSKrishna Gudipati 		break;
606d7be54ccSKrishna Gudipati 
607a36c61f9SKrishna Gudipati 	default:
608a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
609a36c61f9SKrishna Gudipati 	}
610a36c61f9SKrishna Gudipati }
611a36c61f9SKrishna Gudipati 
6125fbe25c7SJing Huang /*
613a36c61f9SKrishna Gudipati  *   Fabric is online - normal operating state.
614a36c61f9SKrishna Gudipati  */
615f7f73812SMaggie Zhang void
616a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
617a36c61f9SKrishna Gudipati 			 enum bfa_fcs_fabric_event event)
618a36c61f9SKrishna Gudipati {
619bc0e2c2aSKrishna Gudipati 	struct bfa_s	*bfa = fabric->fcs->bfa;
620bc0e2c2aSKrishna Gudipati 
621a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
622a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
623a36c61f9SKrishna Gudipati 
624a36c61f9SKrishna Gudipati 	switch (event) {
625a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
626a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
627bc0e2c2aSKrishna Gudipati 		if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
628bc0e2c2aSKrishna Gudipati 			bfa_fcs_lport_offline(&fabric->bport);
629bc0e2c2aSKrishna Gudipati 		} else {
630f7f73812SMaggie Zhang 			bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
631a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_notify_offline(fabric);
632bc0e2c2aSKrishna Gudipati 		}
633a36c61f9SKrishna Gudipati 		break;
634a36c61f9SKrishna Gudipati 
635a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
636a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
637a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
638a36c61f9SKrishna Gudipati 		break;
639a36c61f9SKrishna Gudipati 
640881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_STOP:
641881c1b3cSKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_stopping);
642881c1b3cSKrishna Gudipati 		bfa_fcs_fabric_stop(fabric);
643881c1b3cSKrishna Gudipati 		break;
644881c1b3cSKrishna Gudipati 
645a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_FAILED:
646a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
647f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
648a36c61f9SKrishna Gudipati 		break;
649a36c61f9SKrishna Gudipati 
650a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
651a36c61f9SKrishna Gudipati 		break;
652a36c61f9SKrishna Gudipati 
653a36c61f9SKrishna Gudipati 	default:
654a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
655a36c61f9SKrishna Gudipati 	}
656a36c61f9SKrishna Gudipati }
657a36c61f9SKrishna Gudipati 
6585fbe25c7SJing Huang /*
659a36c61f9SKrishna Gudipati  *   Exchanging virtual fabric parameters.
660a36c61f9SKrishna Gudipati  */
661a36c61f9SKrishna Gudipati static void
662a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
663a36c61f9SKrishna Gudipati 		       enum bfa_fcs_fabric_event event)
664a36c61f9SKrishna Gudipati {
665a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
666a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
667a36c61f9SKrishna Gudipati 
668a36c61f9SKrishna Gudipati 	switch (event) {
669a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CONT_OP:
670a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done);
671a36c61f9SKrishna Gudipati 		break;
672a36c61f9SKrishna Gudipati 
673a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_ISOLATE:
674a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated);
675a36c61f9SKrishna Gudipati 		break;
676a36c61f9SKrishna Gudipati 
677a36c61f9SKrishna Gudipati 	default:
678a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
679a36c61f9SKrishna Gudipati 	}
680a36c61f9SKrishna Gudipati }
681a36c61f9SKrishna Gudipati 
6825fbe25c7SJing Huang /*
683a36c61f9SKrishna Gudipati  *   EVFP exchange complete and VFT tagging is enabled.
684a36c61f9SKrishna Gudipati  */
685a36c61f9SKrishna Gudipati static void
686a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
687a36c61f9SKrishna Gudipati 			    enum bfa_fcs_fabric_event event)
688a36c61f9SKrishna Gudipati {
689a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
690a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
691a36c61f9SKrishna Gudipati }
692a36c61f9SKrishna Gudipati 
6935fbe25c7SJing Huang /*
694a36c61f9SKrishna Gudipati  *   Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
695a36c61f9SKrishna Gudipati  */
696a36c61f9SKrishna Gudipati static void
697a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
698a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
699a36c61f9SKrishna Gudipati {
700a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
701a36c61f9SKrishna Gudipati 	char	pwwn_ptr[BFA_STRING_32];
702a36c61f9SKrishna Gudipati 
703a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
704a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
705a36c61f9SKrishna Gudipati 	wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn);
706a36c61f9SKrishna Gudipati 
70788166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
708a36c61f9SKrishna Gudipati 		"Port is isolated due to VF_ID mismatch. "
709a36c61f9SKrishna Gudipati 		"PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.",
710a36c61f9SKrishna Gudipati 		pwwn_ptr, fabric->fcs->port_vfid,
711a36c61f9SKrishna Gudipati 		fabric->event_arg.swp_vfid);
712a36c61f9SKrishna Gudipati }
713a36c61f9SKrishna Gudipati 
7145fbe25c7SJing Huang /*
715a36c61f9SKrishna Gudipati  *   Fabric is being deleted, awaiting vport delete completions.
716a36c61f9SKrishna Gudipati  */
717a36c61f9SKrishna Gudipati static void
718a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
719a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
720a36c61f9SKrishna Gudipati {
721a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
722a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
723a36c61f9SKrishna Gudipati 
724a36c61f9SKrishna Gudipati 	switch (event) {
725a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELCOMP:
726a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
727f7f73812SMaggie Zhang 		bfa_wc_down(&fabric->fcs->wc);
728a36c61f9SKrishna Gudipati 		break;
729a36c61f9SKrishna Gudipati 
730a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
731a36c61f9SKrishna Gudipati 		break;
732a36c61f9SKrishna Gudipati 
733a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
734a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
735a36c61f9SKrishna Gudipati 		break;
736a36c61f9SKrishna Gudipati 
737a36c61f9SKrishna Gudipati 	default:
738a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
739a36c61f9SKrishna Gudipati 	}
740a36c61f9SKrishna Gudipati }
741a36c61f9SKrishna Gudipati 
742881c1b3cSKrishna Gudipati /*
743881c1b3cSKrishna Gudipati  * Fabric is being stopped, awaiting vport stop completions.
744881c1b3cSKrishna Gudipati  */
745881c1b3cSKrishna Gudipati static void
746881c1b3cSKrishna Gudipati bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric,
747881c1b3cSKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
748881c1b3cSKrishna Gudipati {
749bc0e2c2aSKrishna Gudipati 	struct bfa_s	*bfa = fabric->fcs->bfa;
750bc0e2c2aSKrishna Gudipati 
751881c1b3cSKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
752881c1b3cSKrishna Gudipati 	bfa_trc(fabric->fcs, event);
753a36c61f9SKrishna Gudipati 
754881c1b3cSKrishna Gudipati 	switch (event) {
755881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_STOPCOMP:
756bc0e2c2aSKrishna Gudipati 		if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
757bc0e2c2aSKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
758bc0e2c2aSKrishna Gudipati 		} else {
759881c1b3cSKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
760881c1b3cSKrishna Gudipati 			bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT);
761bc0e2c2aSKrishna Gudipati 		}
762881c1b3cSKrishna Gudipati 		break;
763881c1b3cSKrishna Gudipati 
764881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
765881c1b3cSKrishna Gudipati 		break;
766881c1b3cSKrishna Gudipati 
767881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
768bc0e2c2aSKrishna Gudipati 		if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
769bc0e2c2aSKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
770bc0e2c2aSKrishna Gudipati 		else
771881c1b3cSKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
772881c1b3cSKrishna Gudipati 		break;
773881c1b3cSKrishna Gudipati 
774881c1b3cSKrishna Gudipati 	default:
775881c1b3cSKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
776881c1b3cSKrishna Gudipati 	}
777881c1b3cSKrishna Gudipati }
778881c1b3cSKrishna Gudipati 
779881c1b3cSKrishna Gudipati /*
780881c1b3cSKrishna Gudipati  * Fabric is being stopped, cleanup without FLOGO
781881c1b3cSKrishna Gudipati  */
782881c1b3cSKrishna Gudipati static void
783881c1b3cSKrishna Gudipati bfa_fcs_fabric_sm_cleanup(struct bfa_fcs_fabric_s *fabric,
784881c1b3cSKrishna Gudipati 			  enum bfa_fcs_fabric_event event)
785881c1b3cSKrishna Gudipati {
786881c1b3cSKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
787881c1b3cSKrishna Gudipati 	bfa_trc(fabric->fcs, event);
788881c1b3cSKrishna Gudipati 
789881c1b3cSKrishna Gudipati 	switch (event) {
790881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_STOPCOMP:
791881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LOGOCOMP:
792881c1b3cSKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
793881c1b3cSKrishna Gudipati 		bfa_wc_down(&(fabric->fcs)->wc);
794881c1b3cSKrishna Gudipati 		break;
795881c1b3cSKrishna Gudipati 
796881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
797881c1b3cSKrishna Gudipati 		/*
798881c1b3cSKrishna Gudipati 		 * Ignore - can get this event if we get notified about IOC down
799881c1b3cSKrishna Gudipati 		 * before the fabric completion callbk is done.
800881c1b3cSKrishna Gudipati 		 */
801881c1b3cSKrishna Gudipati 		break;
802881c1b3cSKrishna Gudipati 
803881c1b3cSKrishna Gudipati 	default:
804881c1b3cSKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
805881c1b3cSKrishna Gudipati 	}
806881c1b3cSKrishna Gudipati }
807a36c61f9SKrishna Gudipati 
8085fbe25c7SJing Huang /*
809a36c61f9SKrishna Gudipati  *  fcs_fabric_private fabric private functions
810a36c61f9SKrishna Gudipati  */
811a36c61f9SKrishna Gudipati 
812a36c61f9SKrishna Gudipati static void
813a36c61f9SKrishna Gudipati bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
814a36c61f9SKrishna Gudipati {
815a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
816a36c61f9SKrishna Gudipati 
817a36c61f9SKrishna Gudipati 	port_cfg->roles = BFA_LPORT_ROLE_FCP_IM;
818f7f73812SMaggie Zhang 	port_cfg->nwwn = fabric->fcs->bfa->ioc.attr->nwwn;
819f7f73812SMaggie Zhang 	port_cfg->pwwn = fabric->fcs->bfa->ioc.attr->pwwn;
820a36c61f9SKrishna Gudipati }
821a36c61f9SKrishna Gudipati 
8225fbe25c7SJing Huang /*
823a36c61f9SKrishna Gudipati  * Port Symbolic Name Creation for base port.
824a36c61f9SKrishna Gudipati  */
825a36c61f9SKrishna Gudipati void
826a36c61f9SKrishna Gudipati bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
827a36c61f9SKrishna Gudipati {
828a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
829a36c61f9SKrishna Gudipati 	char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
830a36c61f9SKrishna Gudipati 	struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
831a36c61f9SKrishna Gudipati 
832a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
833a36c61f9SKrishna Gudipati 
834a36c61f9SKrishna Gudipati 	/* Model name/number */
835a36c61f9SKrishna Gudipati 	strncpy((char *)&port_cfg->sym_name, model,
836a36c61f9SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
837a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
838a36c61f9SKrishna Gudipati 		sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
839a36c61f9SKrishna Gudipati 
840a36c61f9SKrishna Gudipati 	/* Driver Version */
841a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
842a36c61f9SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
843a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
844a36c61f9SKrishna Gudipati 		sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
845a36c61f9SKrishna Gudipati 
846a36c61f9SKrishna Gudipati 	/* Host machine name */
847a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name,
848a36c61f9SKrishna Gudipati 		(char *)driver_info->host_machine_name,
849a36c61f9SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
850a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
851a36c61f9SKrishna Gudipati 		sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
852a36c61f9SKrishna Gudipati 
853a36c61f9SKrishna Gudipati 	/*
854a36c61f9SKrishna Gudipati 	 * Host OS Info :
855a36c61f9SKrishna Gudipati 	 * If OS Patch Info is not there, do not truncate any bytes from the
856a36c61f9SKrishna Gudipati 	 * OS name string and instead copy the entire OS info string (64 bytes).
857a36c61f9SKrishna Gudipati 	 */
858a36c61f9SKrishna Gudipati 	if (driver_info->host_os_patch[0] == '\0') {
859a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
860a36c61f9SKrishna Gudipati 			(char *)driver_info->host_os_name,
861a36c61f9SKrishna Gudipati 			BFA_FCS_OS_STR_LEN);
862a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
863a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
864a36c61f9SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
865a36c61f9SKrishna Gudipati 	} else {
866a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
867a36c61f9SKrishna Gudipati 			(char *)driver_info->host_os_name,
868a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
869a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
870a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
871a36c61f9SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
872a36c61f9SKrishna Gudipati 
873a36c61f9SKrishna Gudipati 		/* Append host OS Patch Info */
874a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
875a36c61f9SKrishna Gudipati 			(char *)driver_info->host_os_patch,
876a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
877a36c61f9SKrishna Gudipati 	}
878a36c61f9SKrishna Gudipati 
879a36c61f9SKrishna Gudipati 	/* null terminate */
880a36c61f9SKrishna Gudipati 	port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
881a36c61f9SKrishna Gudipati }
882a36c61f9SKrishna Gudipati 
8835fbe25c7SJing Huang /*
884ce7242b8SKrishna Gudipati  * Node Symbolic Name Creation for base port and all vports
885ce7242b8SKrishna Gudipati  */
886ce7242b8SKrishna Gudipati void
887ce7242b8SKrishna Gudipati bfa_fcs_fabric_nsymb_init(struct bfa_fcs_fabric_s *fabric)
888ce7242b8SKrishna Gudipati {
889ce7242b8SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
890ce7242b8SKrishna Gudipati 	char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
891ce7242b8SKrishna Gudipati 	struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
892ce7242b8SKrishna Gudipati 
893ce7242b8SKrishna Gudipati 	bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
894ce7242b8SKrishna Gudipati 
895ce7242b8SKrishna Gudipati 	/* Model name/number */
896ce7242b8SKrishna Gudipati 	strncpy((char *)&port_cfg->node_sym_name, model,
897ce7242b8SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
898ce7242b8SKrishna Gudipati 	strncat((char *)&port_cfg->node_sym_name,
899ce7242b8SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
900ce7242b8SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
901ce7242b8SKrishna Gudipati 
902ce7242b8SKrishna Gudipati 	/* Driver Version */
903ce7242b8SKrishna Gudipati 	strncat((char *)&port_cfg->node_sym_name, (char *)driver_info->version,
904ce7242b8SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
905ce7242b8SKrishna Gudipati 	strncat((char *)&port_cfg->node_sym_name,
906ce7242b8SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
907ce7242b8SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
908ce7242b8SKrishna Gudipati 
909ce7242b8SKrishna Gudipati 	/* Host machine name */
910ce7242b8SKrishna Gudipati 	strncat((char *)&port_cfg->node_sym_name,
911ce7242b8SKrishna Gudipati 		(char *)driver_info->host_machine_name,
912ce7242b8SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
913ce7242b8SKrishna Gudipati 	strncat((char *)&port_cfg->node_sym_name,
914ce7242b8SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
915ce7242b8SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
916ce7242b8SKrishna Gudipati 
917ce7242b8SKrishna Gudipati 	/* null terminate */
918ce7242b8SKrishna Gudipati 	port_cfg->node_sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
919ce7242b8SKrishna Gudipati }
920ce7242b8SKrishna Gudipati 
921ce7242b8SKrishna Gudipati /*
922a36c61f9SKrishna Gudipati  * bfa lps login completion callback
923a36c61f9SKrishna Gudipati  */
924a36c61f9SKrishna Gudipati void
925a36c61f9SKrishna Gudipati bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
926a36c61f9SKrishna Gudipati {
927a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = uarg;
928a36c61f9SKrishna Gudipati 
929a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
930a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, status);
931a36c61f9SKrishna Gudipati 
932a36c61f9SKrishna Gudipati 	switch (status) {
933a36c61f9SKrishna Gudipati 	case BFA_STATUS_OK:
934a36c61f9SKrishna Gudipati 		fabric->stats.flogi_accepts++;
935a36c61f9SKrishna Gudipati 		break;
936a36c61f9SKrishna Gudipati 
937a36c61f9SKrishna Gudipati 	case BFA_STATUS_INVALID_MAC:
938a36c61f9SKrishna Gudipati 		/* Only for CNA */
939a36c61f9SKrishna Gudipati 		fabric->stats.flogi_acc_err++;
940a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
941a36c61f9SKrishna Gudipati 
942a36c61f9SKrishna Gudipati 		return;
943a36c61f9SKrishna Gudipati 
944a36c61f9SKrishna Gudipati 	case BFA_STATUS_EPROTOCOL:
945f7f73812SMaggie Zhang 		switch (fabric->lps->ext_status) {
946a36c61f9SKrishna Gudipati 		case BFA_EPROTO_BAD_ACCEPT:
947a36c61f9SKrishna Gudipati 			fabric->stats.flogi_acc_err++;
948a36c61f9SKrishna Gudipati 			break;
949a36c61f9SKrishna Gudipati 
950a36c61f9SKrishna Gudipati 		case BFA_EPROTO_UNKNOWN_RSP:
951a36c61f9SKrishna Gudipati 			fabric->stats.flogi_unknown_rsp++;
952a36c61f9SKrishna Gudipati 			break;
953a36c61f9SKrishna Gudipati 
954a36c61f9SKrishna Gudipati 		default:
955a36c61f9SKrishna Gudipati 			break;
956a36c61f9SKrishna Gudipati 		}
957a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
958a36c61f9SKrishna Gudipati 
959a36c61f9SKrishna Gudipati 		return;
960a36c61f9SKrishna Gudipati 
961a36c61f9SKrishna Gudipati 	case BFA_STATUS_FABRIC_RJT:
962a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rejects++;
963a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
964a36c61f9SKrishna Gudipati 		return;
965a36c61f9SKrishna Gudipati 
966a36c61f9SKrishna Gudipati 	default:
967a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rsp_err++;
968a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
969a36c61f9SKrishna Gudipati 		return;
970a36c61f9SKrishna Gudipati 	}
971a36c61f9SKrishna Gudipati 
972f7f73812SMaggie Zhang 	fabric->bb_credit = fabric->lps->pr_bbcred;
973a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bb_credit);
974a36c61f9SKrishna Gudipati 
975f7f73812SMaggie Zhang 	if (!(fabric->lps->brcd_switch))
976f7f73812SMaggie Zhang 		fabric->fabric_name =  fabric->lps->pr_nwwn;
977a36c61f9SKrishna Gudipati 
978a36c61f9SKrishna Gudipati 	/*
979a36c61f9SKrishna Gudipati 	 * Check port type. It should be 1 = F-port.
980a36c61f9SKrishna Gudipati 	 */
981f7f73812SMaggie Zhang 	if (fabric->lps->fport) {
982f7f73812SMaggie Zhang 		fabric->bport.pid = fabric->lps->lp_pid;
983f7f73812SMaggie Zhang 		fabric->is_npiv = fabric->lps->npiv_en;
984f7f73812SMaggie Zhang 		fabric->is_auth = fabric->lps->auth_req;
985a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
986a36c61f9SKrishna Gudipati 	} else {
987a36c61f9SKrishna Gudipati 		/*
988a36c61f9SKrishna Gudipati 		 * Nport-2-Nport direct attached
989a36c61f9SKrishna Gudipati 		 */
990a36c61f9SKrishna Gudipati 		fabric->bport.port_topo.pn2n.rem_port_wwn =
991f7f73812SMaggie Zhang 			fabric->lps->pr_pwwn;
992d7be54ccSKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_N2N;
993a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
994a36c61f9SKrishna Gudipati 	}
995a36c61f9SKrishna Gudipati 
996a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.pid);
997a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->is_npiv);
998a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->is_auth);
999a36c61f9SKrishna Gudipati }
10005fbe25c7SJing Huang /*
1001a36c61f9SKrishna Gudipati  *		Allocate and send FLOGI.
1002a36c61f9SKrishna Gudipati  */
1003a36c61f9SKrishna Gudipati static void
1004a36c61f9SKrishna Gudipati bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
1005a36c61f9SKrishna Gudipati {
1006a36c61f9SKrishna Gudipati 	struct bfa_s		*bfa = fabric->fcs->bfa;
1007a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s	*pcfg = &fabric->bport.port_cfg;
1008bbe37a67SVijaya Mohan Guvva 	u8			alpa = 0;
1009a36c61f9SKrishna Gudipati 
1010be540a99SKrishna Gudipati 
1011a36c61f9SKrishna Gudipati 	bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
1012bbe37a67SVijaya Mohan Guvva 		      pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
1013a36c61f9SKrishna Gudipati 
1014a36c61f9SKrishna Gudipati 	fabric->stats.flogi_sent++;
1015a36c61f9SKrishna Gudipati }
1016a36c61f9SKrishna Gudipati 
1017a36c61f9SKrishna Gudipati static void
1018a36c61f9SKrishna Gudipati bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
1019a36c61f9SKrishna Gudipati {
1020a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1021a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
1022a36c61f9SKrishna Gudipati 
1023a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->fabric_name);
1024a36c61f9SKrishna Gudipati 
1025a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_set_opertype(fabric);
1026a36c61f9SKrishna Gudipati 	fabric->stats.fabric_onlines++;
1027a36c61f9SKrishna Gudipati 
10285fbe25c7SJing Huang 	/*
1029a36c61f9SKrishna Gudipati 	 * notify online event to base and then virtual ports
1030a36c61f9SKrishna Gudipati 	 */
1031a36c61f9SKrishna Gudipati 	bfa_fcs_lport_online(&fabric->bport);
1032a36c61f9SKrishna Gudipati 
1033a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
1034a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1035a36c61f9SKrishna Gudipati 		bfa_fcs_vport_online(vport);
1036a36c61f9SKrishna Gudipati 	}
1037a36c61f9SKrishna Gudipati }
1038a36c61f9SKrishna Gudipati 
1039a36c61f9SKrishna Gudipati static void
1040a36c61f9SKrishna Gudipati bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
1041a36c61f9SKrishna Gudipati {
1042a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1043a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
1044a36c61f9SKrishna Gudipati 
1045a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->fabric_name);
1046a36c61f9SKrishna Gudipati 	fabric->stats.fabric_offlines++;
1047a36c61f9SKrishna Gudipati 
10485fbe25c7SJing Huang 	/*
1049a36c61f9SKrishna Gudipati 	 * notify offline event first to vports and then base port.
1050a36c61f9SKrishna Gudipati 	 */
1051a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
1052a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1053a36c61f9SKrishna Gudipati 		bfa_fcs_vport_offline(vport);
1054a36c61f9SKrishna Gudipati 	}
1055a36c61f9SKrishna Gudipati 
1056a36c61f9SKrishna Gudipati 	bfa_fcs_lport_offline(&fabric->bport);
1057a36c61f9SKrishna Gudipati 
1058a36c61f9SKrishna Gudipati 	fabric->fabric_name = 0;
1059a36c61f9SKrishna Gudipati 	fabric->fabric_ip_addr[0] = 0;
1060a36c61f9SKrishna Gudipati }
1061a36c61f9SKrishna Gudipati 
1062a36c61f9SKrishna Gudipati static void
1063a36c61f9SKrishna Gudipati bfa_fcs_fabric_delay(void *cbarg)
1064a36c61f9SKrishna Gudipati {
1065a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
1066a36c61f9SKrishna Gudipati 
1067a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
1068a36c61f9SKrishna Gudipati }
1069a36c61f9SKrishna Gudipati 
10705fbe25c7SJing Huang /*
1071881c1b3cSKrishna Gudipati  * Stop all vports and wait for vport stop completions.
1072881c1b3cSKrishna Gudipati  */
1073881c1b3cSKrishna Gudipati static void
1074881c1b3cSKrishna Gudipati bfa_fcs_fabric_stop(struct bfa_fcs_fabric_s *fabric)
1075881c1b3cSKrishna Gudipati {
1076881c1b3cSKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1077881c1b3cSKrishna Gudipati 	struct list_head	*qe, *qen;
1078881c1b3cSKrishna Gudipati 
1079881c1b3cSKrishna Gudipati 	bfa_wc_init(&fabric->stop_wc, bfa_fcs_fabric_stop_comp, fabric);
1080881c1b3cSKrishna Gudipati 
1081881c1b3cSKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
1082881c1b3cSKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1083881c1b3cSKrishna Gudipati 		bfa_wc_up(&fabric->stop_wc);
1084881c1b3cSKrishna Gudipati 		bfa_fcs_vport_fcs_stop(vport);
1085881c1b3cSKrishna Gudipati 	}
1086881c1b3cSKrishna Gudipati 
1087881c1b3cSKrishna Gudipati 	bfa_wc_up(&fabric->stop_wc);
1088881c1b3cSKrishna Gudipati 	bfa_fcs_lport_stop(&fabric->bport);
1089881c1b3cSKrishna Gudipati 	bfa_wc_wait(&fabric->stop_wc);
1090881c1b3cSKrishna Gudipati }
1091881c1b3cSKrishna Gudipati 
1092881c1b3cSKrishna Gudipati /*
1093a36c61f9SKrishna Gudipati  * Delete all vports and wait for vport delete completions.
1094a36c61f9SKrishna Gudipati  */
1095a36c61f9SKrishna Gudipati static void
1096a36c61f9SKrishna Gudipati bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
1097a36c61f9SKrishna Gudipati {
1098a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1099a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
1100a36c61f9SKrishna Gudipati 
1101a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
1102a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1103a36c61f9SKrishna Gudipati 		bfa_fcs_vport_fcs_delete(vport);
1104a36c61f9SKrishna Gudipati 	}
1105a36c61f9SKrishna Gudipati 
1106a36c61f9SKrishna Gudipati 	bfa_fcs_lport_delete(&fabric->bport);
1107a36c61f9SKrishna Gudipati 	bfa_wc_wait(&fabric->wc);
1108a36c61f9SKrishna Gudipati }
1109a36c61f9SKrishna Gudipati 
1110a36c61f9SKrishna Gudipati static void
1111a36c61f9SKrishna Gudipati bfa_fcs_fabric_delete_comp(void *cbarg)
1112a36c61f9SKrishna Gudipati {
1113a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
1114a36c61f9SKrishna Gudipati 
1115a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
1116a36c61f9SKrishna Gudipati }
1117a36c61f9SKrishna Gudipati 
1118881c1b3cSKrishna Gudipati static void
1119881c1b3cSKrishna Gudipati bfa_fcs_fabric_stop_comp(void *cbarg)
1120881c1b3cSKrishna Gudipati {
1121881c1b3cSKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
1122881c1b3cSKrishna Gudipati 
1123881c1b3cSKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_STOPCOMP);
1124881c1b3cSKrishna Gudipati }
1125881c1b3cSKrishna Gudipati 
11265fbe25c7SJing Huang /*
1127a36c61f9SKrishna Gudipati  *  fcs_fabric_public fabric public functions
1128a36c61f9SKrishna Gudipati  */
1129a36c61f9SKrishna Gudipati 
11305fbe25c7SJing Huang /*
1131a36c61f9SKrishna Gudipati  * Attach time initialization.
1132a36c61f9SKrishna Gudipati  */
1133a36c61f9SKrishna Gudipati void
1134a36c61f9SKrishna Gudipati bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
1135a36c61f9SKrishna Gudipati {
1136a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1137a36c61f9SKrishna Gudipati 
1138a36c61f9SKrishna Gudipati 	fabric = &fcs->fabric;
11396a18b167SJing Huang 	memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
1140a36c61f9SKrishna Gudipati 
11415fbe25c7SJing Huang 	/*
1142a36c61f9SKrishna Gudipati 	 * Initialize base fabric.
1143a36c61f9SKrishna Gudipati 	 */
1144a36c61f9SKrishna Gudipati 	fabric->fcs = fcs;
1145a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&fabric->vport_q);
1146a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&fabric->vf_q);
1147a36c61f9SKrishna Gudipati 	fabric->lps = bfa_lps_alloc(fcs->bfa);
1148d4b671c5SJing Huang 	WARN_ON(!fabric->lps);
1149a36c61f9SKrishna Gudipati 
11505fbe25c7SJing Huang 	/*
1151a36c61f9SKrishna Gudipati 	 * Initialize fabric delete completion handler. Fabric deletion is
1152a36c61f9SKrishna Gudipati 	 * complete when the last vport delete is complete.
1153a36c61f9SKrishna Gudipati 	 */
1154a36c61f9SKrishna Gudipati 	bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric);
1155a36c61f9SKrishna Gudipati 	bfa_wc_up(&fabric->wc); /* For the base port */
1156a36c61f9SKrishna Gudipati 
1157a36c61f9SKrishna Gudipati 	bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
1158a36c61f9SKrishna Gudipati 	bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
1159a36c61f9SKrishna Gudipati }
1160a36c61f9SKrishna Gudipati 
1161a36c61f9SKrishna Gudipati void
1162a36c61f9SKrishna Gudipati bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
1163a36c61f9SKrishna Gudipati {
1164a36c61f9SKrishna Gudipati 	bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
1165a36c61f9SKrishna Gudipati 	bfa_trc(fcs, 0);
1166a36c61f9SKrishna Gudipati }
1167a36c61f9SKrishna Gudipati 
11685fbe25c7SJing Huang /*
1169a36c61f9SKrishna Gudipati  *   Module cleanup
1170a36c61f9SKrishna Gudipati  */
1171a36c61f9SKrishna Gudipati void
1172a36c61f9SKrishna Gudipati bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
1173a36c61f9SKrishna Gudipati {
1174a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1175a36c61f9SKrishna Gudipati 
1176a36c61f9SKrishna Gudipati 	bfa_trc(fcs, 0);
1177a36c61f9SKrishna Gudipati 
11785fbe25c7SJing Huang 	/*
1179a36c61f9SKrishna Gudipati 	 * Cleanup base fabric.
1180a36c61f9SKrishna Gudipati 	 */
1181a36c61f9SKrishna Gudipati 	fabric = &fcs->fabric;
1182a36c61f9SKrishna Gudipati 	bfa_lps_delete(fabric->lps);
1183a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE);
1184a36c61f9SKrishna Gudipati }
1185a36c61f9SKrishna Gudipati 
11865fbe25c7SJing Huang /*
1187881c1b3cSKrishna Gudipati  * Fabric module stop -- stop FCS actions
1188881c1b3cSKrishna Gudipati  */
1189881c1b3cSKrishna Gudipati void
1190881c1b3cSKrishna Gudipati bfa_fcs_fabric_modstop(struct bfa_fcs_s *fcs)
1191881c1b3cSKrishna Gudipati {
1192881c1b3cSKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1193881c1b3cSKrishna Gudipati 
1194881c1b3cSKrishna Gudipati 	bfa_trc(fcs, 0);
1195881c1b3cSKrishna Gudipati 	fabric = &fcs->fabric;
1196881c1b3cSKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_STOP);
1197881c1b3cSKrishna Gudipati }
1198881c1b3cSKrishna Gudipati 
1199881c1b3cSKrishna Gudipati /*
1200a36c61f9SKrishna Gudipati  * Fabric module start -- kick starts FCS actions
1201a36c61f9SKrishna Gudipati  */
1202a36c61f9SKrishna Gudipati void
1203a36c61f9SKrishna Gudipati bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
1204a36c61f9SKrishna Gudipati {
1205a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1206a36c61f9SKrishna Gudipati 
1207a36c61f9SKrishna Gudipati 	bfa_trc(fcs, 0);
1208a36c61f9SKrishna Gudipati 	fabric = &fcs->fabric;
1209a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
1210a36c61f9SKrishna Gudipati }
1211a36c61f9SKrishna Gudipati 
1212a36c61f9SKrishna Gudipati 
12135fbe25c7SJing Huang /*
1214a36c61f9SKrishna Gudipati  *   Link up notification from BFA physical port module.
1215a36c61f9SKrishna Gudipati  */
1216a36c61f9SKrishna Gudipati void
1217a36c61f9SKrishna Gudipati bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
1218a36c61f9SKrishna Gudipati {
1219a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
1220a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
1221a36c61f9SKrishna Gudipati }
1222a36c61f9SKrishna Gudipati 
12235fbe25c7SJing Huang /*
1224a36c61f9SKrishna Gudipati  *   Link down notification from BFA physical port module.
1225a36c61f9SKrishna Gudipati  */
1226a36c61f9SKrishna Gudipati void
1227a36c61f9SKrishna Gudipati bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
1228a36c61f9SKrishna Gudipati {
1229a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
1230a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
1231a36c61f9SKrishna Gudipati }
1232a36c61f9SKrishna Gudipati 
12335fbe25c7SJing Huang /*
1234a36c61f9SKrishna Gudipati  *   A child vport is being created in the fabric.
1235a36c61f9SKrishna Gudipati  *
1236a36c61f9SKrishna Gudipati  *   Call from vport module at vport creation. A list of base port and vports
1237a36c61f9SKrishna Gudipati  *   belonging to a fabric is maintained to propagate link events.
1238a36c61f9SKrishna Gudipati  *
1239a36c61f9SKrishna Gudipati  *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
1240a36c61f9SKrishna Gudipati  *   param[in] vport  - Vport being created.
1241a36c61f9SKrishna Gudipati  *
1242a36c61f9SKrishna Gudipati  *   @return None (always succeeds)
1243a36c61f9SKrishna Gudipati  */
1244a36c61f9SKrishna Gudipati void
1245a36c61f9SKrishna Gudipati bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
1246a36c61f9SKrishna Gudipati 			struct bfa_fcs_vport_s *vport)
1247a36c61f9SKrishna Gudipati {
12485fbe25c7SJing Huang 	/*
1249a36c61f9SKrishna Gudipati 	 * - add vport to fabric's vport_q
1250a36c61f9SKrishna Gudipati 	 */
1251a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->vf_id);
1252a36c61f9SKrishna Gudipati 
1253a36c61f9SKrishna Gudipati 	list_add_tail(&vport->qe, &fabric->vport_q);
1254a36c61f9SKrishna Gudipati 	fabric->num_vports++;
1255a36c61f9SKrishna Gudipati 	bfa_wc_up(&fabric->wc);
1256a36c61f9SKrishna Gudipati }
1257a36c61f9SKrishna Gudipati 
12585fbe25c7SJing Huang /*
1259a36c61f9SKrishna Gudipati  *   A child vport is being deleted from fabric.
1260a36c61f9SKrishna Gudipati  *
1261a36c61f9SKrishna Gudipati  *   Vport is being deleted.
1262a36c61f9SKrishna Gudipati  */
1263a36c61f9SKrishna Gudipati void
1264a36c61f9SKrishna Gudipati bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
1265a36c61f9SKrishna Gudipati 			struct bfa_fcs_vport_s *vport)
1266a36c61f9SKrishna Gudipati {
1267a36c61f9SKrishna Gudipati 	list_del(&vport->qe);
1268a36c61f9SKrishna Gudipati 	fabric->num_vports--;
1269a36c61f9SKrishna Gudipati 	bfa_wc_down(&fabric->wc);
1270a36c61f9SKrishna Gudipati }
1271a36c61f9SKrishna Gudipati 
1272a36c61f9SKrishna Gudipati 
12735fbe25c7SJing Huang /*
127425985edcSLucas De Marchi  * Lookup for a vport within a fabric given its pwwn
1275a36c61f9SKrishna Gudipati  */
1276a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *
1277a36c61f9SKrishna Gudipati bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
1278a36c61f9SKrishna Gudipati {
1279a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1280a36c61f9SKrishna Gudipati 	struct list_head	      *qe;
1281a36c61f9SKrishna Gudipati 
1282a36c61f9SKrishna Gudipati 	list_for_each(qe, &fabric->vport_q) {
1283a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1284a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_get_pwwn(&vport->lport) == pwwn)
1285a36c61f9SKrishna Gudipati 			return vport;
1286a36c61f9SKrishna Gudipati 	}
1287a36c61f9SKrishna Gudipati 
1288a36c61f9SKrishna Gudipati 	return NULL;
1289a36c61f9SKrishna Gudipati }
1290a36c61f9SKrishna Gudipati 
1291a36c61f9SKrishna Gudipati 
1292a36c61f9SKrishna Gudipati /*
1293a36c61f9SKrishna Gudipati  *  Get OUI of the attached switch.
1294a36c61f9SKrishna Gudipati  *
1295a36c61f9SKrishna Gudipati  *  Note : Use of this function should be avoided as much as possible.
1296a36c61f9SKrishna Gudipati  *         This function should be used only if there is any requirement
1297a36c61f9SKrishna Gudipati *          to check for FOS version below 6.3.
1298a36c61f9SKrishna Gudipati  *         To check if the attached fabric is a brocade fabric, use
1299a36c61f9SKrishna Gudipati  *         bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
1300a36c61f9SKrishna Gudipati  *         or above only.
1301a36c61f9SKrishna Gudipati  */
1302a36c61f9SKrishna Gudipati 
1303a36c61f9SKrishna Gudipati u16
1304a36c61f9SKrishna Gudipati bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
1305a36c61f9SKrishna Gudipati {
1306a36c61f9SKrishna Gudipati 	wwn_t fab_nwwn;
1307a36c61f9SKrishna Gudipati 	u8 *tmp;
1308a36c61f9SKrishna Gudipati 	u16 oui;
1309a36c61f9SKrishna Gudipati 
1310f7f73812SMaggie Zhang 	fab_nwwn = fabric->lps->pr_nwwn;
1311a36c61f9SKrishna Gudipati 
1312a36c61f9SKrishna Gudipati 	tmp = (u8 *)&fab_nwwn;
1313a36c61f9SKrishna Gudipati 	oui = (tmp[3] << 8) | tmp[4];
1314a36c61f9SKrishna Gudipati 
1315a36c61f9SKrishna Gudipati 	return oui;
1316a36c61f9SKrishna Gudipati }
13175fbe25c7SJing Huang /*
1318a36c61f9SKrishna Gudipati  *		Unsolicited frame receive handling.
1319a36c61f9SKrishna Gudipati  */
1320a36c61f9SKrishna Gudipati void
1321a36c61f9SKrishna Gudipati bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1322a36c61f9SKrishna Gudipati 		       u16 len)
1323a36c61f9SKrishna Gudipati {
1324a36c61f9SKrishna Gudipati 	u32	pid = fchs->d_id;
1325a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1326a36c61f9SKrishna Gudipati 	struct list_head	      *qe;
1327a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1328a36c61f9SKrishna Gudipati 	struct fc_logi_s *flogi = (struct fc_logi_s *) els_cmd;
1329a36c61f9SKrishna Gudipati 
1330a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, len);
1331a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, pid);
1332a36c61f9SKrishna Gudipati 
13335fbe25c7SJing Huang 	/*
1334a36c61f9SKrishna Gudipati 	 * Look for our own FLOGI frames being looped back. This means an
1335a36c61f9SKrishna Gudipati 	 * external loopback cable is in place. Our own FLOGI frames are
1336a36c61f9SKrishna Gudipati 	 * sometimes looped back when switch port gets temporarily bypassed.
1337a36c61f9SKrishna Gudipati 	 */
1338f16a1750SMaggie Zhang 	if ((pid == bfa_ntoh3b(FC_FABRIC_PORT)) &&
1339a36c61f9SKrishna Gudipati 	    (els_cmd->els_code == FC_ELS_FLOGI) &&
1340a36c61f9SKrishna Gudipati 	    (flogi->port_name == bfa_fcs_lport_get_pwwn(&fabric->bport))) {
1341a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
1342a36c61f9SKrishna Gudipati 		return;
1343a36c61f9SKrishna Gudipati 	}
1344a36c61f9SKrishna Gudipati 
13455fbe25c7SJing Huang 	/*
1346a36c61f9SKrishna Gudipati 	 * FLOGI/EVFP exchanges should be consumed by base fabric.
1347a36c61f9SKrishna Gudipati 	 */
1348f16a1750SMaggie Zhang 	if (fchs->d_id == bfa_hton3b(FC_FABRIC_PORT)) {
1349a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, pid);
1350a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_process_uf(fabric, fchs, len);
1351a36c61f9SKrishna Gudipati 		return;
1352a36c61f9SKrishna Gudipati 	}
1353a36c61f9SKrishna Gudipati 
1354a36c61f9SKrishna Gudipati 	if (fabric->bport.pid == pid) {
13555fbe25c7SJing Huang 		/*
1356a36c61f9SKrishna Gudipati 		 * All authentication frames should be routed to auth
1357a36c61f9SKrishna Gudipati 		 */
1358a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, els_cmd->els_code);
1359a36c61f9SKrishna Gudipati 		if (els_cmd->els_code == FC_ELS_AUTH) {
1360a36c61f9SKrishna Gudipati 			bfa_trc(fabric->fcs, els_cmd->els_code);
1361a36c61f9SKrishna Gudipati 			return;
1362a36c61f9SKrishna Gudipati 		}
1363a36c61f9SKrishna Gudipati 
1364a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
1365a36c61f9SKrishna Gudipati 		bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
1366a36c61f9SKrishna Gudipati 		return;
1367a36c61f9SKrishna Gudipati 	}
1368a36c61f9SKrishna Gudipati 
13695fbe25c7SJing Huang 	/*
1370a36c61f9SKrishna Gudipati 	 * look for a matching local port ID
1371a36c61f9SKrishna Gudipati 	 */
1372a36c61f9SKrishna Gudipati 	list_for_each(qe, &fabric->vport_q) {
1373a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1374a36c61f9SKrishna Gudipati 		if (vport->lport.pid == pid) {
1375a36c61f9SKrishna Gudipati 			bfa_fcs_lport_uf_recv(&vport->lport, fchs, len);
1376a36c61f9SKrishna Gudipati 			return;
1377a36c61f9SKrishna Gudipati 		}
1378a36c61f9SKrishna Gudipati 	}
137961ba4394SKrishna Gudipati 
138061ba4394SKrishna Gudipati 	if (!bfa_fcs_fabric_is_switched(fabric))
1381a36c61f9SKrishna Gudipati 		bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
138261ba4394SKrishna Gudipati 
138361ba4394SKrishna Gudipati 	bfa_trc(fabric->fcs, fchs->type);
1384a36c61f9SKrishna Gudipati }
1385a36c61f9SKrishna Gudipati 
13865fbe25c7SJing Huang /*
1387a36c61f9SKrishna Gudipati  *		Unsolicited frames to be processed by fabric.
1388a36c61f9SKrishna Gudipati  */
1389a36c61f9SKrishna Gudipati static void
1390a36c61f9SKrishna Gudipati bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1391a36c61f9SKrishna Gudipati 			  u16 len)
1392a36c61f9SKrishna Gudipati {
1393a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1394a36c61f9SKrishna Gudipati 
1395a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, els_cmd->els_code);
1396a36c61f9SKrishna Gudipati 
1397a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
1398a36c61f9SKrishna Gudipati 	case FC_ELS_FLOGI:
1399a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_process_flogi(fabric, fchs, len);
1400a36c61f9SKrishna Gudipati 		break;
1401a36c61f9SKrishna Gudipati 
1402a36c61f9SKrishna Gudipati 	default:
1403a36c61f9SKrishna Gudipati 		/*
1404a36c61f9SKrishna Gudipati 		 * need to generate a LS_RJT
1405a36c61f9SKrishna Gudipati 		 */
1406a36c61f9SKrishna Gudipati 		break;
1407a36c61f9SKrishna Gudipati 	}
1408a36c61f9SKrishna Gudipati }
1409a36c61f9SKrishna Gudipati 
14105fbe25c7SJing Huang /*
1411a36c61f9SKrishna Gudipati  *	Process	incoming FLOGI
1412a36c61f9SKrishna Gudipati  */
1413a36c61f9SKrishna Gudipati static void
1414a36c61f9SKrishna Gudipati bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
1415a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
1416a36c61f9SKrishna Gudipati {
1417a36c61f9SKrishna Gudipati 	struct fc_logi_s *flogi = (struct fc_logi_s *) (fchs + 1);
1418a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *bport = &fabric->bport;
1419a36c61f9SKrishna Gudipati 
1420a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fchs->s_id);
1421a36c61f9SKrishna Gudipati 
1422a36c61f9SKrishna Gudipati 	fabric->stats.flogi_rcvd++;
1423a36c61f9SKrishna Gudipati 	/*
1424a36c61f9SKrishna Gudipati 	 * Check port type. It should be 0 = n-port.
1425a36c61f9SKrishna Gudipati 	 */
1426a36c61f9SKrishna Gudipati 	if (flogi->csp.port_type) {
1427a36c61f9SKrishna Gudipati 		/*
1428a36c61f9SKrishna Gudipati 		 * @todo: may need to send a LS_RJT
1429a36c61f9SKrishna Gudipati 		 */
1430a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, flogi->port_name);
1431a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rejected++;
1432a36c61f9SKrishna Gudipati 		return;
1433a36c61f9SKrishna Gudipati 	}
1434a36c61f9SKrishna Gudipati 
1435ba816ea8SJing Huang 	fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred);
1436a36c61f9SKrishna Gudipati 	bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
1437a36c61f9SKrishna Gudipati 	bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
1438a36c61f9SKrishna Gudipati 
1439a36c61f9SKrishna Gudipati 	/*
1440a36c61f9SKrishna Gudipati 	 * Send a Flogi Acc
1441a36c61f9SKrishna Gudipati 	 */
1442a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_send_flogi_acc(fabric);
1443a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
1444a36c61f9SKrishna Gudipati }
1445a36c61f9SKrishna Gudipati 
1446a36c61f9SKrishna Gudipati static void
1447a36c61f9SKrishna Gudipati bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1448a36c61f9SKrishna Gudipati {
1449a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
1450a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
1451a36c61f9SKrishna Gudipati 	struct bfa_s	  *bfa = fabric->fcs->bfa;
1452a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1453a36c61f9SKrishna Gudipati 	u16	reqlen;
1454a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1455a36c61f9SKrishna Gudipati 
1456c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(fabric->fcs, BFA_FALSE);
14575fbe25c7SJing Huang 	/*
1458a36c61f9SKrishna Gudipati 	 * Do not expect this failure -- expect remote node to retry
1459a36c61f9SKrishna Gudipati 	 */
1460a36c61f9SKrishna Gudipati 	if (!fcxp)
1461a36c61f9SKrishna Gudipati 		return;
1462a36c61f9SKrishna Gudipati 
1463a36c61f9SKrishna Gudipati 	reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1464f16a1750SMaggie Zhang 				    bfa_hton3b(FC_FABRIC_PORT),
1465a36c61f9SKrishna Gudipati 				    n2n_port->reply_oxid, pcfg->pwwn,
1466a36c61f9SKrishna Gudipati 				    pcfg->nwwn,
1467a36c61f9SKrishna Gudipati 				    bfa_fcport_get_maxfrsize(bfa),
1468bbe37a67SVijaya Mohan Guvva 				    bfa_fcport_get_rx_bbcredit(bfa), 0);
1469a36c61f9SKrishna Gudipati 
14703fd45980SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->bfa_tag,
1471a36c61f9SKrishna Gudipati 		      BFA_FALSE, FC_CLASS_3,
1472a36c61f9SKrishna Gudipati 		      reqlen, &fchs, bfa_fcs_fabric_flogiacc_comp, fabric,
1473a36c61f9SKrishna Gudipati 		      FC_MAX_PDUSZ, 0);
1474a36c61f9SKrishna Gudipati }
1475a36c61f9SKrishna Gudipati 
14765fbe25c7SJing Huang /*
1477a36c61f9SKrishna Gudipati  *   Flogi Acc completion callback.
1478a36c61f9SKrishna Gudipati  */
1479a36c61f9SKrishna Gudipati static void
1480a36c61f9SKrishna Gudipati bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1481a36c61f9SKrishna Gudipati 			     bfa_status_t status, u32 rsp_len,
1482a36c61f9SKrishna Gudipati 			     u32 resid_len, struct fchs_s *rspfchs)
1483a36c61f9SKrishna Gudipati {
1484a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
1485a36c61f9SKrishna Gudipati 
1486a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, status);
1487a36c61f9SKrishna Gudipati }
1488a36c61f9SKrishna Gudipati 
14897826f304SKrishna Gudipati 
14907826f304SKrishna Gudipati /*
14917826f304SKrishna Gudipati  * Send AEN notification
14927826f304SKrishna Gudipati  */
14937826f304SKrishna Gudipati static void
14947826f304SKrishna Gudipati bfa_fcs_fabric_aen_post(struct bfa_fcs_lport_s *port,
14957826f304SKrishna Gudipati 			enum bfa_port_aen_event event)
14967826f304SKrishna Gudipati {
14977826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
14987826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
14997826f304SKrishna Gudipati 
15007826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
15017826f304SKrishna Gudipati 	if (!aen_entry)
15027826f304SKrishna Gudipati 		return;
15037826f304SKrishna Gudipati 
15047826f304SKrishna Gudipati 	aen_entry->aen_data.port.pwwn = bfa_fcs_lport_get_pwwn(port);
15057826f304SKrishna Gudipati 	aen_entry->aen_data.port.fwwn = bfa_fcs_lport_get_fabric_name(port);
15067826f304SKrishna Gudipati 
15077826f304SKrishna Gudipati 	/* Send the AEN notification */
15087826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
15097826f304SKrishna Gudipati 				  BFA_AEN_CAT_PORT, event);
15107826f304SKrishna Gudipati }
15117826f304SKrishna Gudipati 
1512a36c61f9SKrishna Gudipati /*
1513a36c61f9SKrishna Gudipati  *
1514a36c61f9SKrishna Gudipati  * @param[in] fabric - fabric
1515a36c61f9SKrishna Gudipati  * @param[in] wwn_t - new fabric name
1516a36c61f9SKrishna Gudipati  *
1517a36c61f9SKrishna Gudipati  * @return - none
1518a36c61f9SKrishna Gudipati  */
1519a36c61f9SKrishna Gudipati void
1520a36c61f9SKrishna Gudipati bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1521a36c61f9SKrishna Gudipati 			       wwn_t fabric_name)
1522a36c61f9SKrishna Gudipati {
1523a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
1524a36c61f9SKrishna Gudipati 	char	pwwn_ptr[BFA_STRING_32];
1525a36c61f9SKrishna Gudipati 	char	fwwn_ptr[BFA_STRING_32];
1526a36c61f9SKrishna Gudipati 
1527a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric_name);
1528a36c61f9SKrishna Gudipati 
1529a36c61f9SKrishna Gudipati 	if (fabric->fabric_name == 0) {
1530a36c61f9SKrishna Gudipati 		/*
1531a36c61f9SKrishna Gudipati 		 * With BRCD switches, we don't get Fabric Name in FLOGI.
1532a36c61f9SKrishna Gudipati 		 * Don't generate a fabric name change event in this case.
1533a36c61f9SKrishna Gudipati 		 */
1534a36c61f9SKrishna Gudipati 		fabric->fabric_name = fabric_name;
1535a36c61f9SKrishna Gudipati 	} else {
1536a36c61f9SKrishna Gudipati 		fabric->fabric_name = fabric_name;
1537a36c61f9SKrishna Gudipati 		wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport));
1538a36c61f9SKrishna Gudipati 		wwn2str(fwwn_ptr,
1539a36c61f9SKrishna Gudipati 			bfa_fcs_lport_get_fabric_name(&fabric->bport));
154088166242SJing Huang 		BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
1541a36c61f9SKrishna Gudipati 			"Base port WWN = %s Fabric WWN = %s\n",
1542a36c61f9SKrishna Gudipati 			pwwn_ptr, fwwn_ptr);
15437826f304SKrishna Gudipati 		bfa_fcs_fabric_aen_post(&fabric->bport,
15447826f304SKrishna Gudipati 				BFA_PORT_AEN_FABRIC_NAME_CHANGE);
1545a36c61f9SKrishna Gudipati 	}
1546a36c61f9SKrishna Gudipati }
1547a36c61f9SKrishna Gudipati 
1548881c1b3cSKrishna Gudipati void
1549881c1b3cSKrishna Gudipati bfa_cb_lps_flogo_comp(void *bfad, void *uarg)
1550881c1b3cSKrishna Gudipati {
1551881c1b3cSKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = uarg;
1552881c1b3cSKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOGOCOMP);
1553881c1b3cSKrishna Gudipati }
1554881c1b3cSKrishna Gudipati 
15555fbe25c7SJing Huang /*
1556a36c61f9SKrishna Gudipati  *	Returns FCS vf structure for a given vf_id.
1557a36c61f9SKrishna Gudipati  *
1558a36c61f9SKrishna Gudipati  *	param[in]	vf_id - VF_ID
1559a36c61f9SKrishna Gudipati  *
1560a36c61f9SKrishna Gudipati  *	return
1561a36c61f9SKrishna Gudipati  *	If lookup succeeds, retuns fcs vf object, otherwise returns NULL
1562a36c61f9SKrishna Gudipati  */
1563a36c61f9SKrishna Gudipati bfa_fcs_vf_t   *
1564a36c61f9SKrishna Gudipati bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id)
1565a36c61f9SKrishna Gudipati {
1566a36c61f9SKrishna Gudipati 	bfa_trc(fcs, vf_id);
1567a36c61f9SKrishna Gudipati 	if (vf_id == FC_VF_ID_NULL)
1568a36c61f9SKrishna Gudipati 		return &fcs->fabric;
1569a36c61f9SKrishna Gudipati 
1570a36c61f9SKrishna Gudipati 	return NULL;
1571a36c61f9SKrishna Gudipati }
1572a36c61f9SKrishna Gudipati 
15735fbe25c7SJing Huang /*
1574b85daafeSKrishna Gudipati  *	Return the list of local logical ports present in the given VF.
1575b85daafeSKrishna Gudipati  *
1576b85daafeSKrishna Gudipati  *	@param[in]	vf	vf for which logical ports are returned
1577b85daafeSKrishna Gudipati  *	@param[out]	lpwwn	returned logical port wwn list
1578b85daafeSKrishna Gudipati  *	@param[in,out]	nlports in:size of lpwwn list;
1579b85daafeSKrishna Gudipati  *				out:total elements present,
1580b85daafeSKrishna Gudipati  *				actual elements returned is limited by the size
1581b85daafeSKrishna Gudipati  */
1582b85daafeSKrishna Gudipati void
1583b85daafeSKrishna Gudipati bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t lpwwn[], int *nlports)
1584b85daafeSKrishna Gudipati {
1585b85daafeSKrishna Gudipati 	struct list_head *qe;
1586b85daafeSKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1587b85daafeSKrishna Gudipati 	int	i = 0;
1588b85daafeSKrishna Gudipati 	struct bfa_fcs_s	*fcs;
1589b85daafeSKrishna Gudipati 
1590b85daafeSKrishna Gudipati 	if (vf == NULL || lpwwn == NULL || *nlports == 0)
1591b85daafeSKrishna Gudipati 		return;
1592b85daafeSKrishna Gudipati 
1593b85daafeSKrishna Gudipati 	fcs = vf->fcs;
1594b85daafeSKrishna Gudipati 
1595b85daafeSKrishna Gudipati 	bfa_trc(fcs, vf->vf_id);
1596b85daafeSKrishna Gudipati 	bfa_trc(fcs, (uint32_t) *nlports);
1597b85daafeSKrishna Gudipati 
1598b85daafeSKrishna Gudipati 	lpwwn[i++] = vf->bport.port_cfg.pwwn;
1599b85daafeSKrishna Gudipati 
1600b85daafeSKrishna Gudipati 	list_for_each(qe, &vf->vport_q) {
1601b85daafeSKrishna Gudipati 		if (i >= *nlports)
1602b85daafeSKrishna Gudipati 			break;
1603b85daafeSKrishna Gudipati 
1604b85daafeSKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1605b85daafeSKrishna Gudipati 		lpwwn[i++] = vport->lport.port_cfg.pwwn;
1606b85daafeSKrishna Gudipati 	}
1607b85daafeSKrishna Gudipati 
1608b85daafeSKrishna Gudipati 	bfa_trc(fcs, i);
1609b85daafeSKrishna Gudipati 	*nlports = i;
1610b85daafeSKrishna Gudipati }
1611b85daafeSKrishna Gudipati 
1612b85daafeSKrishna Gudipati /*
1613a36c61f9SKrishna Gudipati  * BFA FCS PPORT ( physical port)
1614a36c61f9SKrishna Gudipati  */
1615a36c61f9SKrishna Gudipati static void
1616a36c61f9SKrishna Gudipati bfa_fcs_port_event_handler(void *cbarg, enum bfa_port_linkstate event)
1617a36c61f9SKrishna Gudipati {
1618a36c61f9SKrishna Gudipati 	struct bfa_fcs_s      *fcs = cbarg;
1619a36c61f9SKrishna Gudipati 
1620a36c61f9SKrishna Gudipati 	bfa_trc(fcs, event);
1621a36c61f9SKrishna Gudipati 
1622a36c61f9SKrishna Gudipati 	switch (event) {
1623a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKUP:
1624a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_link_up(&fcs->fabric);
1625a36c61f9SKrishna Gudipati 		break;
1626a36c61f9SKrishna Gudipati 
1627a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKDOWN:
1628a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_link_down(&fcs->fabric);
1629a36c61f9SKrishna Gudipati 		break;
1630a36c61f9SKrishna Gudipati 
1631a36c61f9SKrishna Gudipati 	default:
1632d4b671c5SJing Huang 		WARN_ON(1);
1633a36c61f9SKrishna Gudipati 	}
1634a36c61f9SKrishna Gudipati }
1635a36c61f9SKrishna Gudipati 
1636a36c61f9SKrishna Gudipati void
1637a36c61f9SKrishna Gudipati bfa_fcs_port_attach(struct bfa_fcs_s *fcs)
1638a36c61f9SKrishna Gudipati {
1639a36c61f9SKrishna Gudipati 	bfa_fcport_event_register(fcs->bfa, bfa_fcs_port_event_handler, fcs);
1640a36c61f9SKrishna Gudipati }
1641a36c61f9SKrishna Gudipati 
16425fbe25c7SJing Huang /*
1643a36c61f9SKrishna Gudipati  * BFA FCS UF ( Unsolicited Frames)
1644a36c61f9SKrishna Gudipati  */
1645a36c61f9SKrishna Gudipati 
16465fbe25c7SJing Huang /*
1647a36c61f9SKrishna Gudipati  *		BFA callback for unsolicited frame receive handler.
1648a36c61f9SKrishna Gudipati  *
1649a36c61f9SKrishna Gudipati  * @param[in]		cbarg		callback arg for receive handler
1650a36c61f9SKrishna Gudipati  * @param[in]		uf		unsolicited frame descriptor
1651a36c61f9SKrishna Gudipati  *
1652a36c61f9SKrishna Gudipati  * @return None
1653a36c61f9SKrishna Gudipati  */
1654a36c61f9SKrishna Gudipati static void
1655a36c61f9SKrishna Gudipati bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
1656a36c61f9SKrishna Gudipati {
1657a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs = (struct bfa_fcs_s *) cbarg;
1658a36c61f9SKrishna Gudipati 	struct fchs_s	*fchs = bfa_uf_get_frmbuf(uf);
1659a36c61f9SKrishna Gudipati 	u16	len = bfa_uf_get_frmlen(uf);
1660a36c61f9SKrishna Gudipati 	struct fc_vft_s *vft;
1661a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1662a36c61f9SKrishna Gudipati 
16635fbe25c7SJing Huang 	/*
1664a36c61f9SKrishna Gudipati 	 * check for VFT header
1665a36c61f9SKrishna Gudipati 	 */
1666a36c61f9SKrishna Gudipati 	if (fchs->routing == FC_RTG_EXT_HDR &&
1667a36c61f9SKrishna Gudipati 	    fchs->cat_info == FC_CAT_VFT_HDR) {
1668a36c61f9SKrishna Gudipati 		bfa_stats(fcs, uf.tagged);
1669a36c61f9SKrishna Gudipati 		vft = bfa_uf_get_frmbuf(uf);
1670a36c61f9SKrishna Gudipati 		if (fcs->port_vfid == vft->vf_id)
1671a36c61f9SKrishna Gudipati 			fabric = &fcs->fabric;
1672a36c61f9SKrishna Gudipati 		else
1673a36c61f9SKrishna Gudipati 			fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id);
1674a36c61f9SKrishna Gudipati 
16755fbe25c7SJing Huang 		/*
1676a36c61f9SKrishna Gudipati 		 * drop frame if vfid is unknown
1677a36c61f9SKrishna Gudipati 		 */
1678a36c61f9SKrishna Gudipati 		if (!fabric) {
1679d4b671c5SJing Huang 			WARN_ON(1);
1680a36c61f9SKrishna Gudipati 			bfa_stats(fcs, uf.vfid_unknown);
1681a36c61f9SKrishna Gudipati 			bfa_uf_free(uf);
1682a36c61f9SKrishna Gudipati 			return;
1683a36c61f9SKrishna Gudipati 		}
1684a36c61f9SKrishna Gudipati 
16855fbe25c7SJing Huang 		/*
1686a36c61f9SKrishna Gudipati 		 * skip vft header
1687a36c61f9SKrishna Gudipati 		 */
1688a36c61f9SKrishna Gudipati 		fchs = (struct fchs_s *) (vft + 1);
1689a36c61f9SKrishna Gudipati 		len -= sizeof(struct fc_vft_s);
1690a36c61f9SKrishna Gudipati 
1691a36c61f9SKrishna Gudipati 		bfa_trc(fcs, vft->vf_id);
1692a36c61f9SKrishna Gudipati 	} else {
1693a36c61f9SKrishna Gudipati 		bfa_stats(fcs, uf.untagged);
1694a36c61f9SKrishna Gudipati 		fabric = &fcs->fabric;
1695a36c61f9SKrishna Gudipati 	}
1696a36c61f9SKrishna Gudipati 
1697a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[0]);
1698a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[1]);
1699a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[2]);
1700a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[3]);
1701a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[4]);
1702a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[5]);
1703a36c61f9SKrishna Gudipati 	bfa_trc(fcs, len);
1704a36c61f9SKrishna Gudipati 
1705a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_uf_recv(fabric, fchs, len);
1706a36c61f9SKrishna Gudipati 	bfa_uf_free(uf);
1707a36c61f9SKrishna Gudipati }
1708a36c61f9SKrishna Gudipati 
1709a36c61f9SKrishna Gudipati void
1710a36c61f9SKrishna Gudipati bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
1711a36c61f9SKrishna Gudipati {
1712a36c61f9SKrishna Gudipati 	bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
1713a36c61f9SKrishna Gudipati }
1714