xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs.c (revision 7826f304)
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 
185fbe25c7SJing Huang /*
197725ccfdSJing Huang  *  bfa_fcs.c BFA FCS main
207725ccfdSJing Huang  */
217725ccfdSJing Huang 
22f16a1750SMaggie Zhang #include "bfad_drv.h"
237826f304SKrishna Gudipati #include "bfad_im.h"
24a36c61f9SKrishna Gudipati #include "bfa_fcs.h"
25a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h"
26a36c61f9SKrishna Gudipati 
27a36c61f9SKrishna Gudipati BFA_TRC_FILE(FCS, FCS);
287725ccfdSJing Huang 
295fbe25c7SJing Huang /*
307725ccfdSJing Huang  * FCS sub-modules
317725ccfdSJing Huang  */
327725ccfdSJing Huang struct bfa_fcs_mod_s {
3382794a2eSKrishna Gudipati 	void		(*attach) (struct bfa_fcs_s *fcs);
347725ccfdSJing Huang 	void		(*modinit) (struct bfa_fcs_s *fcs);
357725ccfdSJing Huang 	void		(*modexit) (struct bfa_fcs_s *fcs);
367725ccfdSJing Huang };
377725ccfdSJing Huang 
387725ccfdSJing Huang #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
397725ccfdSJing Huang 
407725ccfdSJing Huang static struct bfa_fcs_mod_s fcs_modules[] = {
41a36c61f9SKrishna Gudipati 	{ bfa_fcs_port_attach, NULL, NULL },
4282794a2eSKrishna Gudipati 	{ bfa_fcs_uf_attach, NULL, NULL },
4382794a2eSKrishna Gudipati 	{ bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
4482794a2eSKrishna Gudipati 	  bfa_fcs_fabric_modexit },
457725ccfdSJing Huang };
467725ccfdSJing Huang 
475fbe25c7SJing Huang /*
487725ccfdSJing Huang  *  fcs_api BFA FCS API
497725ccfdSJing Huang  */
507725ccfdSJing Huang 
517725ccfdSJing Huang static void
527725ccfdSJing Huang bfa_fcs_exit_comp(void *fcs_cbarg)
537725ccfdSJing Huang {
547725ccfdSJing Huang 	struct bfa_fcs_s      *fcs = fcs_cbarg;
557725ccfdSJing Huang 	struct bfad_s         *bfad = fcs->bfad;
567725ccfdSJing Huang 
577725ccfdSJing Huang 	complete(&bfad->comp);
587725ccfdSJing Huang }
597725ccfdSJing Huang 
607725ccfdSJing Huang 
617725ccfdSJing Huang 
625fbe25c7SJing Huang /*
637725ccfdSJing Huang  *  fcs_api BFA FCS API
647725ccfdSJing Huang  */
657725ccfdSJing Huang 
665fbe25c7SJing Huang /*
6782794a2eSKrishna Gudipati  * fcs attach -- called once to initialize data structures at driver attach time
687725ccfdSJing Huang  */
697725ccfdSJing Huang void
7082794a2eSKrishna Gudipati bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
717725ccfdSJing Huang 	       bfa_boolean_t min_cfg)
727725ccfdSJing Huang {
737725ccfdSJing Huang 	int		i;
747725ccfdSJing Huang 	struct bfa_fcs_mod_s  *mod;
757725ccfdSJing Huang 
767725ccfdSJing Huang 	fcs->bfa = bfa;
777725ccfdSJing Huang 	fcs->bfad = bfad;
787725ccfdSJing Huang 	fcs->min_cfg = min_cfg;
797725ccfdSJing Huang 
80f7f73812SMaggie Zhang 	bfa->fcs = BFA_TRUE;
817725ccfdSJing Huang 	fcbuild_init();
827725ccfdSJing Huang 
83a36c61f9SKrishna Gudipati 	for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
847725ccfdSJing Huang 		mod = &fcs_modules[i];
8582794a2eSKrishna Gudipati 		if (mod->attach)
8682794a2eSKrishna Gudipati 			mod->attach(fcs);
8782794a2eSKrishna Gudipati 	}
8882794a2eSKrishna Gudipati }
8982794a2eSKrishna Gudipati 
905fbe25c7SJing Huang /*
9182794a2eSKrishna Gudipati  * fcs initialization, called once after bfa initialization is complete
9282794a2eSKrishna Gudipati  */
9382794a2eSKrishna Gudipati void
9482794a2eSKrishna Gudipati bfa_fcs_init(struct bfa_fcs_s *fcs)
9582794a2eSKrishna Gudipati {
9675332a70SKrishna Gudipati 	int	i;
9782794a2eSKrishna Gudipati 	struct bfa_fcs_mod_s  *mod;
9882794a2eSKrishna Gudipati 
99a36c61f9SKrishna Gudipati 	for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
10082794a2eSKrishna Gudipati 		mod = &fcs_modules[i];
10182794a2eSKrishna Gudipati 		if (mod->modinit)
1027725ccfdSJing Huang 			mod->modinit(fcs);
1037725ccfdSJing Huang 	}
10475332a70SKrishna Gudipati }
10575332a70SKrishna Gudipati 
10675332a70SKrishna Gudipati /*
10775332a70SKrishna Gudipati  * FCS update cfg - reset the pwwn/nwwn of fabric base logical port
10875332a70SKrishna Gudipati  * with values learned during bfa_init firmware GETATTR REQ.
10975332a70SKrishna Gudipati  */
11075332a70SKrishna Gudipati void
11175332a70SKrishna Gudipati bfa_fcs_update_cfg(struct bfa_fcs_s *fcs)
11275332a70SKrishna Gudipati {
11375332a70SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = &fcs->fabric;
11475332a70SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
11575332a70SKrishna Gudipati 	struct bfa_ioc_s *ioc = &fabric->fcs->bfa->ioc;
11675332a70SKrishna Gudipati 
11775332a70SKrishna Gudipati 	port_cfg->nwwn = ioc->attr->nwwn;
11875332a70SKrishna Gudipati 	port_cfg->pwwn = ioc->attr->pwwn;
11975332a70SKrishna Gudipati }
12075332a70SKrishna Gudipati 
12175332a70SKrishna Gudipati /*
12275332a70SKrishna Gudipati  * fcs pbc vport initialization
12375332a70SKrishna Gudipati  */
12475332a70SKrishna Gudipati void
12575332a70SKrishna Gudipati bfa_fcs_pbc_vport_init(struct bfa_fcs_s *fcs)
12675332a70SKrishna Gudipati {
12775332a70SKrishna Gudipati 	int i, npbc_vports;
12875332a70SKrishna Gudipati 	struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];
12975332a70SKrishna Gudipati 
130d9883548SJing Huang 	/* Initialize pbc vports */
131d9883548SJing Huang 	if (!fcs->min_cfg) {
132d9883548SJing Huang 		npbc_vports =
133d9883548SJing Huang 			bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
134d9883548SJing Huang 		for (i = 0; i < npbc_vports; i++)
135d9883548SJing Huang 			bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
136d9883548SJing Huang 	}
1377725ccfdSJing Huang }
1387725ccfdSJing Huang 
1395fbe25c7SJing Huang /*
140a36c61f9SKrishna Gudipati  *	brief
1417725ccfdSJing Huang  *		FCS driver details initialization.
1427725ccfdSJing Huang  *
1437725ccfdSJing Huang  *	param[in]		fcs		FCS instance
1447725ccfdSJing Huang  *	param[in]		driver_info	Driver Details
1457725ccfdSJing Huang  *
1467725ccfdSJing Huang  *	return None
1477725ccfdSJing Huang  */
1487725ccfdSJing Huang void
1497725ccfdSJing Huang bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
1507725ccfdSJing Huang 			struct bfa_fcs_driver_info_s *driver_info)
1517725ccfdSJing Huang {
1527725ccfdSJing Huang 
1537725ccfdSJing Huang 	fcs->driver_info = *driver_info;
1547725ccfdSJing Huang 
1557725ccfdSJing Huang 	bfa_fcs_fabric_psymb_init(&fcs->fabric);
1567725ccfdSJing Huang }
1577725ccfdSJing Huang 
1585fbe25c7SJing Huang /*
159a36c61f9SKrishna Gudipati  *	brief
1607725ccfdSJing Huang  *		FCS instance cleanup and exit.
1617725ccfdSJing Huang  *
1627725ccfdSJing Huang  *	param[in]		fcs			FCS instance
1637725ccfdSJing Huang  *	return None
1647725ccfdSJing Huang  */
1657725ccfdSJing Huang void
1667725ccfdSJing Huang bfa_fcs_exit(struct bfa_fcs_s *fcs)
1677725ccfdSJing Huang {
1687725ccfdSJing Huang 	struct bfa_fcs_mod_s  *mod;
169a36c61f9SKrishna Gudipati 	int		nmods, i;
1707725ccfdSJing Huang 
1717725ccfdSJing Huang 	bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
1727725ccfdSJing Huang 
173a36c61f9SKrishna Gudipati 	nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
174a36c61f9SKrishna Gudipati 
175a36c61f9SKrishna Gudipati 	for (i = 0; i < nmods; i++) {
1767725ccfdSJing Huang 
1777725ccfdSJing Huang 		mod = &fcs_modules[i];
17882794a2eSKrishna Gudipati 		if (mod->modexit) {
17982794a2eSKrishna Gudipati 			bfa_wc_up(&fcs->wc);
1807725ccfdSJing Huang 			mod->modexit(fcs);
1817725ccfdSJing Huang 		}
18282794a2eSKrishna Gudipati 	}
1837725ccfdSJing Huang 
1847725ccfdSJing Huang 	bfa_wc_wait(&fcs->wc);
1857725ccfdSJing Huang }
1867725ccfdSJing Huang 
1877725ccfdSJing Huang 
1885fbe25c7SJing Huang /*
189a36c61f9SKrishna Gudipati  * Fabric module implementation.
190a36c61f9SKrishna Gudipati  */
1917725ccfdSJing Huang 
192a36c61f9SKrishna Gudipati #define BFA_FCS_FABRIC_RETRY_DELAY	(2000)	/* Milliseconds */
193a36c61f9SKrishna Gudipati #define BFA_FCS_FABRIC_CLEANUP_DELAY	(10000)	/* Milliseconds */
194a36c61f9SKrishna Gudipati 
195a36c61f9SKrishna Gudipati #define bfa_fcs_fabric_set_opertype(__fabric) do {			\
196a36c61f9SKrishna Gudipati 	if (bfa_fcport_get_topology((__fabric)->fcs->bfa)		\
197d7be54ccSKrishna Gudipati 				== BFA_PORT_TOPOLOGY_P2P) {		\
198d7be54ccSKrishna Gudipati 		if (fabric->fab_type == BFA_FCS_FABRIC_SWITCHED)	\
199a36c61f9SKrishna Gudipati 			(__fabric)->oper_type = BFA_PORT_TYPE_NPORT;	\
200a36c61f9SKrishna Gudipati 		else							\
201d7be54ccSKrishna Gudipati 			(__fabric)->oper_type = BFA_PORT_TYPE_P2P;	\
202d7be54ccSKrishna Gudipati 	} else								\
203a36c61f9SKrishna Gudipati 		(__fabric)->oper_type = BFA_PORT_TYPE_NLPORT;		\
204a36c61f9SKrishna Gudipati } while (0)
205a36c61f9SKrishna Gudipati 
206a36c61f9SKrishna Gudipati /*
207a36c61f9SKrishna Gudipati  * forward declarations
208a36c61f9SKrishna Gudipati  */
209a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
210a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
211a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
212a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
213a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delay(void *cbarg);
214a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
215a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delete_comp(void *cbarg);
216a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
217a36c61f9SKrishna Gudipati 				      struct fchs_s *fchs, u16 len);
218a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
219a36c61f9SKrishna Gudipati 					 struct fchs_s *fchs, u16 len);
220a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
221a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
222a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp, void *cbarg,
223a36c61f9SKrishna Gudipati 					 bfa_status_t status,
224a36c61f9SKrishna Gudipati 					 u32 rsp_len,
225a36c61f9SKrishna Gudipati 					 u32 resid_len,
226a36c61f9SKrishna Gudipati 					 struct fchs_s *rspfchs);
227be540a99SKrishna Gudipati static u8 bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric);
228be540a99SKrishna Gudipati static bfa_boolean_t bfa_fcs_fabric_is_bbscn_enabled(
229be540a99SKrishna Gudipati 				struct bfa_fcs_fabric_s *fabric);
230a36c61f9SKrishna Gudipati 
231a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
232a36c61f9SKrishna Gudipati 					 enum bfa_fcs_fabric_event event);
233a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
234a36c61f9SKrishna Gudipati 					  enum bfa_fcs_fabric_event event);
235a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
236a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
237a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
238a36c61f9SKrishna Gudipati 					enum bfa_fcs_fabric_event event);
239a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
240a36c61f9SKrishna Gudipati 					      enum bfa_fcs_fabric_event event);
241a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
242a36c61f9SKrishna Gudipati 				       enum bfa_fcs_fabric_event event);
243a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
244a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
245a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
246a36c61f9SKrishna Gudipati 				       enum bfa_fcs_fabric_event event);
247a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
248a36c61f9SKrishna Gudipati 					    enum bfa_fcs_fabric_event event);
249a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
250a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
251a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
252a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
2535fbe25c7SJing Huang /*
254a36c61f9SKrishna Gudipati  *   Beginning state before fabric creation.
255a36c61f9SKrishna Gudipati  */
256a36c61f9SKrishna Gudipati static void
257a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
258a36c61f9SKrishna Gudipati 			 enum bfa_fcs_fabric_event event)
259a36c61f9SKrishna Gudipati {
260a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
261a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
262a36c61f9SKrishna Gudipati 
263a36c61f9SKrishna Gudipati 	switch (event) {
264a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CREATE:
265a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
266a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_init(fabric);
267a36c61f9SKrishna Gudipati 		bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
268a36c61f9SKrishna Gudipati 		break;
269a36c61f9SKrishna Gudipati 
270a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
271a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
272a36c61f9SKrishna Gudipati 		break;
273a36c61f9SKrishna Gudipati 
274a36c61f9SKrishna Gudipati 	default:
275a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
276a36c61f9SKrishna Gudipati 	}
277a36c61f9SKrishna Gudipati }
278a36c61f9SKrishna Gudipati 
2795fbe25c7SJing Huang /*
280a36c61f9SKrishna Gudipati  *   Beginning state before fabric creation.
281a36c61f9SKrishna Gudipati  */
282a36c61f9SKrishna Gudipati static void
283a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
284a36c61f9SKrishna Gudipati 			  enum bfa_fcs_fabric_event event)
285a36c61f9SKrishna Gudipati {
286a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
287a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
288a36c61f9SKrishna Gudipati 
289a36c61f9SKrishna Gudipati 	switch (event) {
290a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_START:
291a36c61f9SKrishna Gudipati 		if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
292a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
293a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_login(fabric);
294a36c61f9SKrishna Gudipati 		} else
295a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
296a36c61f9SKrishna Gudipati 		break;
297a36c61f9SKrishna Gudipati 
298a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
299a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
300a36c61f9SKrishna Gudipati 		break;
301a36c61f9SKrishna Gudipati 
302a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
303dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
304dd5aaf45SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
305a36c61f9SKrishna Gudipati 		break;
306a36c61f9SKrishna Gudipati 
307a36c61f9SKrishna Gudipati 	default:
308a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
309a36c61f9SKrishna Gudipati 	}
310a36c61f9SKrishna Gudipati }
311a36c61f9SKrishna Gudipati 
3125fbe25c7SJing Huang /*
313a36c61f9SKrishna Gudipati  *   Link is down, awaiting LINK UP event from port. This is also the
314a36c61f9SKrishna Gudipati  *   first state at fabric creation.
315a36c61f9SKrishna Gudipati  */
316a36c61f9SKrishna Gudipati static void
317a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
318a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
319a36c61f9SKrishna Gudipati {
320a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
321a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
322a36c61f9SKrishna Gudipati 
323a36c61f9SKrishna Gudipati 	switch (event) {
324a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
325a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
326a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_login(fabric);
327a36c61f9SKrishna Gudipati 		break;
328a36c61f9SKrishna Gudipati 
329a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
330a36c61f9SKrishna Gudipati 		break;
331a36c61f9SKrishna Gudipati 
332a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
333a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
334a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
335a36c61f9SKrishna Gudipati 		break;
336a36c61f9SKrishna Gudipati 
337a36c61f9SKrishna Gudipati 	default:
338a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
339a36c61f9SKrishna Gudipati 	}
340a36c61f9SKrishna Gudipati }
341a36c61f9SKrishna Gudipati 
3425fbe25c7SJing Huang /*
343a36c61f9SKrishna Gudipati  *   FLOGI is in progress, awaiting FLOGI reply.
344a36c61f9SKrishna Gudipati  */
345a36c61f9SKrishna Gudipati static void
346a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
347a36c61f9SKrishna Gudipati 			enum bfa_fcs_fabric_event event)
348a36c61f9SKrishna Gudipati {
349a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
350a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
351a36c61f9SKrishna Gudipati 
352a36c61f9SKrishna Gudipati 	switch (event) {
353a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CONT_OP:
354a36c61f9SKrishna Gudipati 
355a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
356be540a99SKrishna Gudipati 					   fabric->bb_credit,
357be540a99SKrishna Gudipati 					   bfa_fcs_fabric_oper_bbscn(fabric));
358a36c61f9SKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
359a36c61f9SKrishna Gudipati 
360a36c61f9SKrishna Gudipati 		if (fabric->auth_reqd && fabric->is_auth) {
361a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth);
362a36c61f9SKrishna Gudipati 			bfa_trc(fabric->fcs, event);
363a36c61f9SKrishna Gudipati 		} else {
364a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
365a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_notify_online(fabric);
366a36c61f9SKrishna Gudipati 		}
367a36c61f9SKrishna Gudipati 		break;
368a36c61f9SKrishna Gudipati 
369a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
370a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry);
371a36c61f9SKrishna Gudipati 		bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer,
372a36c61f9SKrishna Gudipati 				bfa_fcs_fabric_delay, fabric,
373a36c61f9SKrishna Gudipati 				BFA_FCS_FABRIC_RETRY_DELAY);
374a36c61f9SKrishna Gudipati 		break;
375a36c61f9SKrishna Gudipati 
376a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LOOPBACK:
377a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
378f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
379a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_set_opertype(fabric);
380a36c61f9SKrishna Gudipati 		break;
381a36c61f9SKrishna Gudipati 
382a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
383a36c61f9SKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_N2N;
384a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
385be540a99SKrishna Gudipati 					   fabric->bb_credit,
386be540a99SKrishna Gudipati 					   bfa_fcs_fabric_oper_bbscn(fabric));
387a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_online(fabric);
388a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
389a36c61f9SKrishna Gudipati 		break;
390a36c61f9SKrishna Gudipati 
391a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
392a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
393f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
394a36c61f9SKrishna Gudipati 		break;
395a36c61f9SKrishna Gudipati 
396a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
397a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
398f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
399a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
400a36c61f9SKrishna Gudipati 		break;
401a36c61f9SKrishna Gudipati 
402a36c61f9SKrishna Gudipati 	default:
403a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
404a36c61f9SKrishna Gudipati 	}
405a36c61f9SKrishna Gudipati }
406a36c61f9SKrishna Gudipati 
407a36c61f9SKrishna Gudipati 
408a36c61f9SKrishna Gudipati static void
409a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
410a36c61f9SKrishna Gudipati 			      enum bfa_fcs_fabric_event event)
411a36c61f9SKrishna Gudipati {
412a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
413a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
414a36c61f9SKrishna Gudipati 
415a36c61f9SKrishna Gudipati 	switch (event) {
416a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELAYED:
417a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
418a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_login(fabric);
419a36c61f9SKrishna Gudipati 		break;
420a36c61f9SKrishna Gudipati 
421a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
422a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
423a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fabric->delay_timer);
424a36c61f9SKrishna Gudipati 		break;
425a36c61f9SKrishna Gudipati 
426a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
427a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
428a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fabric->delay_timer);
429a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
430a36c61f9SKrishna Gudipati 		break;
431a36c61f9SKrishna Gudipati 
432a36c61f9SKrishna Gudipati 	default:
433a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
434a36c61f9SKrishna Gudipati 	}
435a36c61f9SKrishna Gudipati }
436a36c61f9SKrishna Gudipati 
4375fbe25c7SJing Huang /*
438a36c61f9SKrishna Gudipati  *   Authentication is in progress, awaiting authentication results.
439a36c61f9SKrishna Gudipati  */
440a36c61f9SKrishna Gudipati static void
441a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
442a36c61f9SKrishna Gudipati 		       enum bfa_fcs_fabric_event event)
443a36c61f9SKrishna Gudipati {
444a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
445a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
446a36c61f9SKrishna Gudipati 
447a36c61f9SKrishna Gudipati 	switch (event) {
448a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_FAILED:
449a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
450f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
451a36c61f9SKrishna Gudipati 		break;
452a36c61f9SKrishna Gudipati 
453a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
454a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
455a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_online(fabric);
456a36c61f9SKrishna Gudipati 		break;
457a36c61f9SKrishna Gudipati 
458a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_PERF_EVFP:
459a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp);
460a36c61f9SKrishna Gudipati 		break;
461a36c61f9SKrishna Gudipati 
462a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
463a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
464f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
465a36c61f9SKrishna Gudipati 		break;
466a36c61f9SKrishna Gudipati 
467a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
468a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
469a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
470a36c61f9SKrishna Gudipati 		break;
471a36c61f9SKrishna Gudipati 
472a36c61f9SKrishna Gudipati 	default:
473a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
474a36c61f9SKrishna Gudipati 	}
475a36c61f9SKrishna Gudipati }
476a36c61f9SKrishna Gudipati 
4775fbe25c7SJing Huang /*
478a36c61f9SKrishna Gudipati  *   Authentication failed
479a36c61f9SKrishna Gudipati  */
480f7f73812SMaggie Zhang void
481a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
482a36c61f9SKrishna Gudipati 			      enum bfa_fcs_fabric_event event)
483a36c61f9SKrishna Gudipati {
484a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
485a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
486a36c61f9SKrishna Gudipati 
487a36c61f9SKrishna Gudipati 	switch (event) {
488a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
489a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
490a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
491a36c61f9SKrishna Gudipati 		break;
492a36c61f9SKrishna Gudipati 
493a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
494a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
495a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
496a36c61f9SKrishna Gudipati 		break;
497a36c61f9SKrishna Gudipati 
498a36c61f9SKrishna Gudipati 	default:
499a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
500a36c61f9SKrishna Gudipati 	}
501a36c61f9SKrishna Gudipati }
502a36c61f9SKrishna Gudipati 
5035fbe25c7SJing Huang /*
504a36c61f9SKrishna Gudipati  *   Port is in loopback mode.
505a36c61f9SKrishna Gudipati  */
506f7f73812SMaggie Zhang void
507a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
508a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
509a36c61f9SKrishna Gudipati {
510a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
511a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
512a36c61f9SKrishna Gudipati 
513a36c61f9SKrishna Gudipati 	switch (event) {
514a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
515a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
516a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
517a36c61f9SKrishna Gudipati 		break;
518a36c61f9SKrishna Gudipati 
519a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
520a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
521a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
522a36c61f9SKrishna Gudipati 		break;
523a36c61f9SKrishna Gudipati 
524a36c61f9SKrishna Gudipati 	default:
525a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
526a36c61f9SKrishna Gudipati 	}
527a36c61f9SKrishna Gudipati }
528a36c61f9SKrishna Gudipati 
5295fbe25c7SJing Huang /*
530a36c61f9SKrishna Gudipati  *   There is no attached fabric - private loop or NPort-to-NPort topology.
531a36c61f9SKrishna Gudipati  */
532a36c61f9SKrishna Gudipati static void
533a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
534a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
535a36c61f9SKrishna Gudipati {
536a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
537a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
538a36c61f9SKrishna Gudipati 
539a36c61f9SKrishna Gudipati 	switch (event) {
540a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
541a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
542f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
543a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
544a36c61f9SKrishna Gudipati 		break;
545a36c61f9SKrishna Gudipati 
546a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
547a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
548a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
549a36c61f9SKrishna Gudipati 		break;
550a36c61f9SKrishna Gudipati 
551a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
552a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, fabric->bb_credit);
553a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
554be540a99SKrishna Gudipati 					   fabric->bb_credit,
555be540a99SKrishna Gudipati 					   bfa_fcs_fabric_oper_bbscn(fabric));
556a36c61f9SKrishna Gudipati 		break;
557a36c61f9SKrishna Gudipati 
558d7be54ccSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
559d7be54ccSKrishna Gudipati 		break;
560d7be54ccSKrishna Gudipati 
561a36c61f9SKrishna Gudipati 	default:
562a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
563a36c61f9SKrishna Gudipati 	}
564a36c61f9SKrishna Gudipati }
565a36c61f9SKrishna Gudipati 
5665fbe25c7SJing Huang /*
567a36c61f9SKrishna Gudipati  *   Fabric is online - normal operating state.
568a36c61f9SKrishna Gudipati  */
569f7f73812SMaggie Zhang void
570a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
571a36c61f9SKrishna Gudipati 			 enum bfa_fcs_fabric_event event)
572a36c61f9SKrishna Gudipati {
573a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
574a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
575a36c61f9SKrishna Gudipati 
576a36c61f9SKrishna Gudipati 	switch (event) {
577a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
578a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
579f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
580a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
581a36c61f9SKrishna Gudipati 		break;
582a36c61f9SKrishna Gudipati 
583a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
584a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
585a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
586a36c61f9SKrishna Gudipati 		break;
587a36c61f9SKrishna Gudipati 
588a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_FAILED:
589a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
590f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
591a36c61f9SKrishna Gudipati 		break;
592a36c61f9SKrishna Gudipati 
593a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
594a36c61f9SKrishna Gudipati 		break;
595a36c61f9SKrishna Gudipati 
596a36c61f9SKrishna Gudipati 	default:
597a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
598a36c61f9SKrishna Gudipati 	}
599a36c61f9SKrishna Gudipati }
600a36c61f9SKrishna Gudipati 
6015fbe25c7SJing Huang /*
602a36c61f9SKrishna Gudipati  *   Exchanging virtual fabric parameters.
603a36c61f9SKrishna Gudipati  */
604a36c61f9SKrishna Gudipati static void
605a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
606a36c61f9SKrishna Gudipati 		       enum bfa_fcs_fabric_event event)
607a36c61f9SKrishna Gudipati {
608a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
609a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
610a36c61f9SKrishna Gudipati 
611a36c61f9SKrishna Gudipati 	switch (event) {
612a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CONT_OP:
613a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done);
614a36c61f9SKrishna Gudipati 		break;
615a36c61f9SKrishna Gudipati 
616a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_ISOLATE:
617a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated);
618a36c61f9SKrishna Gudipati 		break;
619a36c61f9SKrishna Gudipati 
620a36c61f9SKrishna Gudipati 	default:
621a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
622a36c61f9SKrishna Gudipati 	}
623a36c61f9SKrishna Gudipati }
624a36c61f9SKrishna Gudipati 
6255fbe25c7SJing Huang /*
626a36c61f9SKrishna Gudipati  *   EVFP exchange complete and VFT tagging is enabled.
627a36c61f9SKrishna Gudipati  */
628a36c61f9SKrishna Gudipati static void
629a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
630a36c61f9SKrishna Gudipati 			    enum bfa_fcs_fabric_event event)
631a36c61f9SKrishna Gudipati {
632a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
633a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
634a36c61f9SKrishna Gudipati }
635a36c61f9SKrishna Gudipati 
6365fbe25c7SJing Huang /*
637a36c61f9SKrishna Gudipati  *   Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
638a36c61f9SKrishna Gudipati  */
639a36c61f9SKrishna Gudipati static void
640a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
641a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
642a36c61f9SKrishna Gudipati {
643a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
644a36c61f9SKrishna Gudipati 	char	pwwn_ptr[BFA_STRING_32];
645a36c61f9SKrishna Gudipati 
646a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
647a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
648a36c61f9SKrishna Gudipati 	wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn);
649a36c61f9SKrishna Gudipati 
65088166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
651a36c61f9SKrishna Gudipati 		"Port is isolated due to VF_ID mismatch. "
652a36c61f9SKrishna Gudipati 		"PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.",
653a36c61f9SKrishna Gudipati 		pwwn_ptr, fabric->fcs->port_vfid,
654a36c61f9SKrishna Gudipati 		fabric->event_arg.swp_vfid);
655a36c61f9SKrishna Gudipati }
656a36c61f9SKrishna Gudipati 
6575fbe25c7SJing Huang /*
658a36c61f9SKrishna Gudipati  *   Fabric is being deleted, awaiting vport delete completions.
659a36c61f9SKrishna Gudipati  */
660a36c61f9SKrishna Gudipati static void
661a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
662a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
663a36c61f9SKrishna Gudipati {
664a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
665a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
666a36c61f9SKrishna Gudipati 
667a36c61f9SKrishna Gudipati 	switch (event) {
668a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELCOMP:
669a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
670f7f73812SMaggie Zhang 		bfa_wc_down(&fabric->fcs->wc);
671a36c61f9SKrishna Gudipati 		break;
672a36c61f9SKrishna Gudipati 
673a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
674a36c61f9SKrishna Gudipati 		break;
675a36c61f9SKrishna Gudipati 
676a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
677a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
678a36c61f9SKrishna Gudipati 		break;
679a36c61f9SKrishna Gudipati 
680a36c61f9SKrishna Gudipati 	default:
681a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
682a36c61f9SKrishna Gudipati 	}
683a36c61f9SKrishna Gudipati }
684a36c61f9SKrishna Gudipati 
685a36c61f9SKrishna Gudipati 
686a36c61f9SKrishna Gudipati 
6875fbe25c7SJing Huang /*
688a36c61f9SKrishna Gudipati  *  fcs_fabric_private fabric private functions
689a36c61f9SKrishna Gudipati  */
690a36c61f9SKrishna Gudipati 
691a36c61f9SKrishna Gudipati static void
692a36c61f9SKrishna Gudipati bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
693a36c61f9SKrishna Gudipati {
694a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
695a36c61f9SKrishna Gudipati 
696a36c61f9SKrishna Gudipati 	port_cfg->roles = BFA_LPORT_ROLE_FCP_IM;
697f7f73812SMaggie Zhang 	port_cfg->nwwn = fabric->fcs->bfa->ioc.attr->nwwn;
698f7f73812SMaggie Zhang 	port_cfg->pwwn = fabric->fcs->bfa->ioc.attr->pwwn;
699a36c61f9SKrishna Gudipati }
700a36c61f9SKrishna Gudipati 
7015fbe25c7SJing Huang /*
702a36c61f9SKrishna Gudipati  * Port Symbolic Name Creation for base port.
703a36c61f9SKrishna Gudipati  */
704a36c61f9SKrishna Gudipati void
705a36c61f9SKrishna Gudipati bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
706a36c61f9SKrishna Gudipati {
707a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
708a36c61f9SKrishna Gudipati 	char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
709a36c61f9SKrishna Gudipati 	struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
710a36c61f9SKrishna Gudipati 
711a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
712a36c61f9SKrishna Gudipati 
713a36c61f9SKrishna Gudipati 	/* Model name/number */
714a36c61f9SKrishna Gudipati 	strncpy((char *)&port_cfg->sym_name, model,
715a36c61f9SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
716a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
717a36c61f9SKrishna Gudipati 		sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
718a36c61f9SKrishna Gudipati 
719a36c61f9SKrishna Gudipati 	/* Driver Version */
720a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
721a36c61f9SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
722a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
723a36c61f9SKrishna Gudipati 		sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
724a36c61f9SKrishna Gudipati 
725a36c61f9SKrishna Gudipati 	/* Host machine name */
726a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name,
727a36c61f9SKrishna Gudipati 		(char *)driver_info->host_machine_name,
728a36c61f9SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
729a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
730a36c61f9SKrishna Gudipati 		sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
731a36c61f9SKrishna Gudipati 
732a36c61f9SKrishna Gudipati 	/*
733a36c61f9SKrishna Gudipati 	 * Host OS Info :
734a36c61f9SKrishna Gudipati 	 * If OS Patch Info is not there, do not truncate any bytes from the
735a36c61f9SKrishna Gudipati 	 * OS name string and instead copy the entire OS info string (64 bytes).
736a36c61f9SKrishna Gudipati 	 */
737a36c61f9SKrishna Gudipati 	if (driver_info->host_os_patch[0] == '\0') {
738a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
739a36c61f9SKrishna Gudipati 			(char *)driver_info->host_os_name,
740a36c61f9SKrishna Gudipati 			BFA_FCS_OS_STR_LEN);
741a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
742a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
743a36c61f9SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
744a36c61f9SKrishna Gudipati 	} else {
745a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
746a36c61f9SKrishna Gudipati 			(char *)driver_info->host_os_name,
747a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
748a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
749a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
750a36c61f9SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
751a36c61f9SKrishna Gudipati 
752a36c61f9SKrishna Gudipati 		/* Append host OS Patch Info */
753a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
754a36c61f9SKrishna Gudipati 			(char *)driver_info->host_os_patch,
755a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
756a36c61f9SKrishna Gudipati 	}
757a36c61f9SKrishna Gudipati 
758a36c61f9SKrishna Gudipati 	/* null terminate */
759a36c61f9SKrishna Gudipati 	port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
760a36c61f9SKrishna Gudipati }
761a36c61f9SKrishna Gudipati 
7625fbe25c7SJing Huang /*
763a36c61f9SKrishna Gudipati  * bfa lps login completion callback
764a36c61f9SKrishna Gudipati  */
765a36c61f9SKrishna Gudipati void
766a36c61f9SKrishna Gudipati bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
767a36c61f9SKrishna Gudipati {
768a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = uarg;
769a36c61f9SKrishna Gudipati 
770a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
771a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, status);
772a36c61f9SKrishna Gudipati 
773a36c61f9SKrishna Gudipati 	switch (status) {
774a36c61f9SKrishna Gudipati 	case BFA_STATUS_OK:
775a36c61f9SKrishna Gudipati 		fabric->stats.flogi_accepts++;
776a36c61f9SKrishna Gudipati 		break;
777a36c61f9SKrishna Gudipati 
778a36c61f9SKrishna Gudipati 	case BFA_STATUS_INVALID_MAC:
779a36c61f9SKrishna Gudipati 		/* Only for CNA */
780a36c61f9SKrishna Gudipati 		fabric->stats.flogi_acc_err++;
781a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
782a36c61f9SKrishna Gudipati 
783a36c61f9SKrishna Gudipati 		return;
784a36c61f9SKrishna Gudipati 
785a36c61f9SKrishna Gudipati 	case BFA_STATUS_EPROTOCOL:
786f7f73812SMaggie Zhang 		switch (fabric->lps->ext_status) {
787a36c61f9SKrishna Gudipati 		case BFA_EPROTO_BAD_ACCEPT:
788a36c61f9SKrishna Gudipati 			fabric->stats.flogi_acc_err++;
789a36c61f9SKrishna Gudipati 			break;
790a36c61f9SKrishna Gudipati 
791a36c61f9SKrishna Gudipati 		case BFA_EPROTO_UNKNOWN_RSP:
792a36c61f9SKrishna Gudipati 			fabric->stats.flogi_unknown_rsp++;
793a36c61f9SKrishna Gudipati 			break;
794a36c61f9SKrishna Gudipati 
795a36c61f9SKrishna Gudipati 		default:
796a36c61f9SKrishna Gudipati 			break;
797a36c61f9SKrishna Gudipati 		}
798a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
799a36c61f9SKrishna Gudipati 
800a36c61f9SKrishna Gudipati 		return;
801a36c61f9SKrishna Gudipati 
802a36c61f9SKrishna Gudipati 	case BFA_STATUS_FABRIC_RJT:
803a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rejects++;
804be540a99SKrishna Gudipati 		if (fabric->lps->lsrjt_rsn == FC_LS_RJT_RSN_LOGICAL_ERROR &&
805be540a99SKrishna Gudipati 		    fabric->lps->lsrjt_expl == FC_LS_RJT_EXP_NO_ADDL_INFO)
806be540a99SKrishna Gudipati 			fabric->fcs->bbscn_flogi_rjt = BFA_TRUE;
807be540a99SKrishna Gudipati 
808a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
809a36c61f9SKrishna Gudipati 		return;
810a36c61f9SKrishna Gudipati 
811a36c61f9SKrishna Gudipati 	default:
812a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rsp_err++;
813a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
814a36c61f9SKrishna Gudipati 		return;
815a36c61f9SKrishna Gudipati 	}
816a36c61f9SKrishna Gudipati 
817f7f73812SMaggie Zhang 	fabric->bb_credit = fabric->lps->pr_bbcred;
818a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bb_credit);
819a36c61f9SKrishna Gudipati 
820f7f73812SMaggie Zhang 	if (!(fabric->lps->brcd_switch))
821f7f73812SMaggie Zhang 		fabric->fabric_name =  fabric->lps->pr_nwwn;
822a36c61f9SKrishna Gudipati 
823a36c61f9SKrishna Gudipati 	/*
824a36c61f9SKrishna Gudipati 	 * Check port type. It should be 1 = F-port.
825a36c61f9SKrishna Gudipati 	 */
826f7f73812SMaggie Zhang 	if (fabric->lps->fport) {
827f7f73812SMaggie Zhang 		fabric->bport.pid = fabric->lps->lp_pid;
828f7f73812SMaggie Zhang 		fabric->is_npiv = fabric->lps->npiv_en;
829f7f73812SMaggie Zhang 		fabric->is_auth = fabric->lps->auth_req;
830a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
831a36c61f9SKrishna Gudipati 	} else {
832a36c61f9SKrishna Gudipati 		/*
833a36c61f9SKrishna Gudipati 		 * Nport-2-Nport direct attached
834a36c61f9SKrishna Gudipati 		 */
835a36c61f9SKrishna Gudipati 		fabric->bport.port_topo.pn2n.rem_port_wwn =
836f7f73812SMaggie Zhang 			fabric->lps->pr_pwwn;
837d7be54ccSKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_N2N;
838a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
839a36c61f9SKrishna Gudipati 	}
840a36c61f9SKrishna Gudipati 
841a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.pid);
842a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->is_npiv);
843a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->is_auth);
844a36c61f9SKrishna Gudipati }
8455fbe25c7SJing Huang /*
846a36c61f9SKrishna Gudipati  *		Allocate and send FLOGI.
847a36c61f9SKrishna Gudipati  */
848a36c61f9SKrishna Gudipati static void
849a36c61f9SKrishna Gudipati bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
850a36c61f9SKrishna Gudipati {
851a36c61f9SKrishna Gudipati 	struct bfa_s		*bfa = fabric->fcs->bfa;
852a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s	*pcfg = &fabric->bport.port_cfg;
853be540a99SKrishna Gudipati 	u8			alpa = 0, bb_scn = 0;
854a36c61f9SKrishna Gudipati 
855a36c61f9SKrishna Gudipati 	if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
856a36c61f9SKrishna Gudipati 		alpa = bfa_fcport_get_myalpa(bfa);
857a36c61f9SKrishna Gudipati 
858be540a99SKrishna Gudipati 	if (bfa_fcs_fabric_is_bbscn_enabled(fabric) &&
859be540a99SKrishna Gudipati 	    (!fabric->fcs->bbscn_flogi_rjt))
860be540a99SKrishna Gudipati 		bb_scn = BFA_FCS_PORT_DEF_BB_SCN;
861be540a99SKrishna Gudipati 
862a36c61f9SKrishna Gudipati 	bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
863be540a99SKrishna Gudipati 		      pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd, bb_scn);
864a36c61f9SKrishna Gudipati 
865a36c61f9SKrishna Gudipati 	fabric->stats.flogi_sent++;
866a36c61f9SKrishna Gudipati }
867a36c61f9SKrishna Gudipati 
868a36c61f9SKrishna Gudipati static void
869a36c61f9SKrishna Gudipati bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
870a36c61f9SKrishna Gudipati {
871a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
872a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
873a36c61f9SKrishna Gudipati 
874a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->fabric_name);
875a36c61f9SKrishna Gudipati 
876a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_set_opertype(fabric);
877a36c61f9SKrishna Gudipati 	fabric->stats.fabric_onlines++;
878a36c61f9SKrishna Gudipati 
8795fbe25c7SJing Huang 	/*
880a36c61f9SKrishna Gudipati 	 * notify online event to base and then virtual ports
881a36c61f9SKrishna Gudipati 	 */
882a36c61f9SKrishna Gudipati 	bfa_fcs_lport_online(&fabric->bport);
883a36c61f9SKrishna Gudipati 
884a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
885a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
886a36c61f9SKrishna Gudipati 		bfa_fcs_vport_online(vport);
887a36c61f9SKrishna Gudipati 	}
888a36c61f9SKrishna Gudipati }
889a36c61f9SKrishna Gudipati 
890a36c61f9SKrishna Gudipati static void
891a36c61f9SKrishna Gudipati bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
892a36c61f9SKrishna Gudipati {
893a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
894a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
895a36c61f9SKrishna Gudipati 
896a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->fabric_name);
897a36c61f9SKrishna Gudipati 	fabric->stats.fabric_offlines++;
898a36c61f9SKrishna Gudipati 
8995fbe25c7SJing Huang 	/*
900a36c61f9SKrishna Gudipati 	 * notify offline event first to vports and then base port.
901a36c61f9SKrishna Gudipati 	 */
902a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
903a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
904a36c61f9SKrishna Gudipati 		bfa_fcs_vport_offline(vport);
905a36c61f9SKrishna Gudipati 	}
906a36c61f9SKrishna Gudipati 
907a36c61f9SKrishna Gudipati 	bfa_fcs_lport_offline(&fabric->bport);
908a36c61f9SKrishna Gudipati 
909a36c61f9SKrishna Gudipati 	fabric->fabric_name = 0;
910a36c61f9SKrishna Gudipati 	fabric->fabric_ip_addr[0] = 0;
911a36c61f9SKrishna Gudipati }
912a36c61f9SKrishna Gudipati 
913a36c61f9SKrishna Gudipati static void
914a36c61f9SKrishna Gudipati bfa_fcs_fabric_delay(void *cbarg)
915a36c61f9SKrishna Gudipati {
916a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
917a36c61f9SKrishna Gudipati 
918a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
919a36c61f9SKrishna Gudipati }
920a36c61f9SKrishna Gudipati 
9215fbe25c7SJing Huang /*
922be540a99SKrishna Gudipati  * Computes operating BB_SCN value
923be540a99SKrishna Gudipati  */
924be540a99SKrishna Gudipati static u8
925be540a99SKrishna Gudipati bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric)
926be540a99SKrishna Gudipati {
927be540a99SKrishna Gudipati 	u8	pr_bbscn = fabric->lps->pr_bbscn;
928d7be54ccSKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fabric->fcs->bfa);
929be540a99SKrishna Gudipati 
930d7be54ccSKrishna Gudipati 	if (!(fcport->cfg.bb_scn_state && pr_bbscn))
931be540a99SKrishna Gudipati 		return 0;
932be540a99SKrishna Gudipati 
933be540a99SKrishna Gudipati 	/* return max of local/remote bb_scn values */
934be540a99SKrishna Gudipati 	return ((pr_bbscn > BFA_FCS_PORT_DEF_BB_SCN) ?
935be540a99SKrishna Gudipati 		pr_bbscn : BFA_FCS_PORT_DEF_BB_SCN);
936be540a99SKrishna Gudipati }
937be540a99SKrishna Gudipati 
938be540a99SKrishna Gudipati /*
939be540a99SKrishna Gudipati  * Check if BB_SCN can be enabled.
940be540a99SKrishna Gudipati  */
941be540a99SKrishna Gudipati static bfa_boolean_t
942be540a99SKrishna Gudipati bfa_fcs_fabric_is_bbscn_enabled(struct bfa_fcs_fabric_s *fabric)
943be540a99SKrishna Gudipati {
944d7be54ccSKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fabric->fcs->bfa);
945d7be54ccSKrishna Gudipati 
946be540a99SKrishna Gudipati 	if (bfa_ioc_get_fcmode(&fabric->fcs->bfa->ioc) &&
947d7be54ccSKrishna Gudipati 			fcport->cfg.bb_scn_state &&
948be540a99SKrishna Gudipati 			!bfa_fcport_is_qos_enabled(fabric->fcs->bfa) &&
949be540a99SKrishna Gudipati 			!bfa_fcport_is_trunk_enabled(fabric->fcs->bfa))
950be540a99SKrishna Gudipati 		return BFA_TRUE;
951be540a99SKrishna Gudipati 	else
952be540a99SKrishna Gudipati 		return BFA_FALSE;
953be540a99SKrishna Gudipati }
954be540a99SKrishna Gudipati 
955be540a99SKrishna Gudipati /*
956a36c61f9SKrishna Gudipati  * Delete all vports and wait for vport delete completions.
957a36c61f9SKrishna Gudipati  */
958a36c61f9SKrishna Gudipati static void
959a36c61f9SKrishna Gudipati bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
960a36c61f9SKrishna Gudipati {
961a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
962a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
963a36c61f9SKrishna Gudipati 
964a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
965a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
966a36c61f9SKrishna Gudipati 		bfa_fcs_vport_fcs_delete(vport);
967a36c61f9SKrishna Gudipati 	}
968a36c61f9SKrishna Gudipati 
969a36c61f9SKrishna Gudipati 	bfa_fcs_lport_delete(&fabric->bport);
970a36c61f9SKrishna Gudipati 	bfa_wc_wait(&fabric->wc);
971a36c61f9SKrishna Gudipati }
972a36c61f9SKrishna Gudipati 
973a36c61f9SKrishna Gudipati static void
974a36c61f9SKrishna Gudipati bfa_fcs_fabric_delete_comp(void *cbarg)
975a36c61f9SKrishna Gudipati {
976a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
977a36c61f9SKrishna Gudipati 
978a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
979a36c61f9SKrishna Gudipati }
980a36c61f9SKrishna Gudipati 
9815fbe25c7SJing Huang /*
982a36c61f9SKrishna Gudipati  *  fcs_fabric_public fabric public functions
983a36c61f9SKrishna Gudipati  */
984a36c61f9SKrishna Gudipati 
9855fbe25c7SJing Huang /*
986a36c61f9SKrishna Gudipati  * Attach time initialization.
987a36c61f9SKrishna Gudipati  */
988a36c61f9SKrishna Gudipati void
989a36c61f9SKrishna Gudipati bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
990a36c61f9SKrishna Gudipati {
991a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
992a36c61f9SKrishna Gudipati 
993a36c61f9SKrishna Gudipati 	fabric = &fcs->fabric;
9946a18b167SJing Huang 	memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
995a36c61f9SKrishna Gudipati 
9965fbe25c7SJing Huang 	/*
997a36c61f9SKrishna Gudipati 	 * Initialize base fabric.
998a36c61f9SKrishna Gudipati 	 */
999a36c61f9SKrishna Gudipati 	fabric->fcs = fcs;
1000a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&fabric->vport_q);
1001a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&fabric->vf_q);
1002a36c61f9SKrishna Gudipati 	fabric->lps = bfa_lps_alloc(fcs->bfa);
1003d4b671c5SJing Huang 	WARN_ON(!fabric->lps);
1004a36c61f9SKrishna Gudipati 
10055fbe25c7SJing Huang 	/*
1006a36c61f9SKrishna Gudipati 	 * Initialize fabric delete completion handler. Fabric deletion is
1007a36c61f9SKrishna Gudipati 	 * complete when the last vport delete is complete.
1008a36c61f9SKrishna Gudipati 	 */
1009a36c61f9SKrishna Gudipati 	bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric);
1010a36c61f9SKrishna Gudipati 	bfa_wc_up(&fabric->wc); /* For the base port */
1011a36c61f9SKrishna Gudipati 
1012a36c61f9SKrishna Gudipati 	bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
1013a36c61f9SKrishna Gudipati 	bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
1014a36c61f9SKrishna Gudipati }
1015a36c61f9SKrishna Gudipati 
1016a36c61f9SKrishna Gudipati void
1017a36c61f9SKrishna Gudipati bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
1018a36c61f9SKrishna Gudipati {
1019a36c61f9SKrishna Gudipati 	bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
1020a36c61f9SKrishna Gudipati 	bfa_trc(fcs, 0);
1021a36c61f9SKrishna Gudipati }
1022a36c61f9SKrishna Gudipati 
10235fbe25c7SJing Huang /*
1024a36c61f9SKrishna Gudipati  *   Module cleanup
1025a36c61f9SKrishna Gudipati  */
1026a36c61f9SKrishna Gudipati void
1027a36c61f9SKrishna Gudipati bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
1028a36c61f9SKrishna Gudipati {
1029a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1030a36c61f9SKrishna Gudipati 
1031a36c61f9SKrishna Gudipati 	bfa_trc(fcs, 0);
1032a36c61f9SKrishna Gudipati 
10335fbe25c7SJing Huang 	/*
1034a36c61f9SKrishna Gudipati 	 * Cleanup base fabric.
1035a36c61f9SKrishna Gudipati 	 */
1036a36c61f9SKrishna Gudipati 	fabric = &fcs->fabric;
1037a36c61f9SKrishna Gudipati 	bfa_lps_delete(fabric->lps);
1038a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE);
1039a36c61f9SKrishna Gudipati }
1040a36c61f9SKrishna Gudipati 
10415fbe25c7SJing Huang /*
1042a36c61f9SKrishna Gudipati  * Fabric module start -- kick starts FCS actions
1043a36c61f9SKrishna Gudipati  */
1044a36c61f9SKrishna Gudipati void
1045a36c61f9SKrishna Gudipati bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
1046a36c61f9SKrishna Gudipati {
1047a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1048a36c61f9SKrishna Gudipati 
1049a36c61f9SKrishna Gudipati 	bfa_trc(fcs, 0);
1050a36c61f9SKrishna Gudipati 	fabric = &fcs->fabric;
1051a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
1052a36c61f9SKrishna Gudipati }
1053a36c61f9SKrishna Gudipati 
1054a36c61f9SKrishna Gudipati 
10555fbe25c7SJing Huang /*
1056a36c61f9SKrishna Gudipati  *   Link up notification from BFA physical port module.
1057a36c61f9SKrishna Gudipati  */
1058a36c61f9SKrishna Gudipati void
1059a36c61f9SKrishna Gudipati bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
1060a36c61f9SKrishna Gudipati {
1061a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
1062a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
1063a36c61f9SKrishna Gudipati }
1064a36c61f9SKrishna Gudipati 
10655fbe25c7SJing Huang /*
1066a36c61f9SKrishna Gudipati  *   Link down notification from BFA physical port module.
1067a36c61f9SKrishna Gudipati  */
1068a36c61f9SKrishna Gudipati void
1069a36c61f9SKrishna Gudipati bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
1070a36c61f9SKrishna Gudipati {
1071a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
1072be540a99SKrishna Gudipati 	fabric->fcs->bbscn_flogi_rjt = BFA_FALSE;
1073a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
1074a36c61f9SKrishna Gudipati }
1075a36c61f9SKrishna Gudipati 
10765fbe25c7SJing Huang /*
1077a36c61f9SKrishna Gudipati  *   A child vport is being created in the fabric.
1078a36c61f9SKrishna Gudipati  *
1079a36c61f9SKrishna Gudipati  *   Call from vport module at vport creation. A list of base port and vports
1080a36c61f9SKrishna Gudipati  *   belonging to a fabric is maintained to propagate link events.
1081a36c61f9SKrishna Gudipati  *
1082a36c61f9SKrishna Gudipati  *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
1083a36c61f9SKrishna Gudipati  *   param[in] vport  - Vport being created.
1084a36c61f9SKrishna Gudipati  *
1085a36c61f9SKrishna Gudipati  *   @return None (always succeeds)
1086a36c61f9SKrishna Gudipati  */
1087a36c61f9SKrishna Gudipati void
1088a36c61f9SKrishna Gudipati bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
1089a36c61f9SKrishna Gudipati 			struct bfa_fcs_vport_s *vport)
1090a36c61f9SKrishna Gudipati {
10915fbe25c7SJing Huang 	/*
1092a36c61f9SKrishna Gudipati 	 * - add vport to fabric's vport_q
1093a36c61f9SKrishna Gudipati 	 */
1094a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->vf_id);
1095a36c61f9SKrishna Gudipati 
1096a36c61f9SKrishna Gudipati 	list_add_tail(&vport->qe, &fabric->vport_q);
1097a36c61f9SKrishna Gudipati 	fabric->num_vports++;
1098a36c61f9SKrishna Gudipati 	bfa_wc_up(&fabric->wc);
1099a36c61f9SKrishna Gudipati }
1100a36c61f9SKrishna Gudipati 
11015fbe25c7SJing Huang /*
1102a36c61f9SKrishna Gudipati  *   A child vport is being deleted from fabric.
1103a36c61f9SKrishna Gudipati  *
1104a36c61f9SKrishna Gudipati  *   Vport is being deleted.
1105a36c61f9SKrishna Gudipati  */
1106a36c61f9SKrishna Gudipati void
1107a36c61f9SKrishna Gudipati bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
1108a36c61f9SKrishna Gudipati 			struct bfa_fcs_vport_s *vport)
1109a36c61f9SKrishna Gudipati {
1110a36c61f9SKrishna Gudipati 	list_del(&vport->qe);
1111a36c61f9SKrishna Gudipati 	fabric->num_vports--;
1112a36c61f9SKrishna Gudipati 	bfa_wc_down(&fabric->wc);
1113a36c61f9SKrishna Gudipati }
1114a36c61f9SKrishna Gudipati 
1115a36c61f9SKrishna Gudipati 
11165fbe25c7SJing Huang /*
111725985edcSLucas De Marchi  * Lookup for a vport within a fabric given its pwwn
1118a36c61f9SKrishna Gudipati  */
1119a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *
1120a36c61f9SKrishna Gudipati bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
1121a36c61f9SKrishna Gudipati {
1122a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1123a36c61f9SKrishna Gudipati 	struct list_head	      *qe;
1124a36c61f9SKrishna Gudipati 
1125a36c61f9SKrishna Gudipati 	list_for_each(qe, &fabric->vport_q) {
1126a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1127a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_get_pwwn(&vport->lport) == pwwn)
1128a36c61f9SKrishna Gudipati 			return vport;
1129a36c61f9SKrishna Gudipati 	}
1130a36c61f9SKrishna Gudipati 
1131a36c61f9SKrishna Gudipati 	return NULL;
1132a36c61f9SKrishna Gudipati }
1133a36c61f9SKrishna Gudipati 
1134a36c61f9SKrishna Gudipati 
1135a36c61f9SKrishna Gudipati /*
1136a36c61f9SKrishna Gudipati  *  Get OUI of the attached switch.
1137a36c61f9SKrishna Gudipati  *
1138a36c61f9SKrishna Gudipati  *  Note : Use of this function should be avoided as much as possible.
1139a36c61f9SKrishna Gudipati  *         This function should be used only if there is any requirement
1140a36c61f9SKrishna Gudipati *          to check for FOS version below 6.3.
1141a36c61f9SKrishna Gudipati  *         To check if the attached fabric is a brocade fabric, use
1142a36c61f9SKrishna Gudipati  *         bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
1143a36c61f9SKrishna Gudipati  *         or above only.
1144a36c61f9SKrishna Gudipati  */
1145a36c61f9SKrishna Gudipati 
1146a36c61f9SKrishna Gudipati u16
1147a36c61f9SKrishna Gudipati bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
1148a36c61f9SKrishna Gudipati {
1149a36c61f9SKrishna Gudipati 	wwn_t fab_nwwn;
1150a36c61f9SKrishna Gudipati 	u8 *tmp;
1151a36c61f9SKrishna Gudipati 	u16 oui;
1152a36c61f9SKrishna Gudipati 
1153f7f73812SMaggie Zhang 	fab_nwwn = fabric->lps->pr_nwwn;
1154a36c61f9SKrishna Gudipati 
1155a36c61f9SKrishna Gudipati 	tmp = (u8 *)&fab_nwwn;
1156a36c61f9SKrishna Gudipati 	oui = (tmp[3] << 8) | tmp[4];
1157a36c61f9SKrishna Gudipati 
1158a36c61f9SKrishna Gudipati 	return oui;
1159a36c61f9SKrishna Gudipati }
11605fbe25c7SJing Huang /*
1161a36c61f9SKrishna Gudipati  *		Unsolicited frame receive handling.
1162a36c61f9SKrishna Gudipati  */
1163a36c61f9SKrishna Gudipati void
1164a36c61f9SKrishna Gudipati bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1165a36c61f9SKrishna Gudipati 		       u16 len)
1166a36c61f9SKrishna Gudipati {
1167a36c61f9SKrishna Gudipati 	u32	pid = fchs->d_id;
1168a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1169a36c61f9SKrishna Gudipati 	struct list_head	      *qe;
1170a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1171a36c61f9SKrishna Gudipati 	struct fc_logi_s *flogi = (struct fc_logi_s *) els_cmd;
1172a36c61f9SKrishna Gudipati 
1173a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, len);
1174a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, pid);
1175a36c61f9SKrishna Gudipati 
11765fbe25c7SJing Huang 	/*
1177a36c61f9SKrishna Gudipati 	 * Look for our own FLOGI frames being looped back. This means an
1178a36c61f9SKrishna Gudipati 	 * external loopback cable is in place. Our own FLOGI frames are
1179a36c61f9SKrishna Gudipati 	 * sometimes looped back when switch port gets temporarily bypassed.
1180a36c61f9SKrishna Gudipati 	 */
1181f16a1750SMaggie Zhang 	if ((pid == bfa_ntoh3b(FC_FABRIC_PORT)) &&
1182a36c61f9SKrishna Gudipati 	    (els_cmd->els_code == FC_ELS_FLOGI) &&
1183a36c61f9SKrishna Gudipati 	    (flogi->port_name == bfa_fcs_lport_get_pwwn(&fabric->bport))) {
1184a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
1185a36c61f9SKrishna Gudipati 		return;
1186a36c61f9SKrishna Gudipati 	}
1187a36c61f9SKrishna Gudipati 
11885fbe25c7SJing Huang 	/*
1189a36c61f9SKrishna Gudipati 	 * FLOGI/EVFP exchanges should be consumed by base fabric.
1190a36c61f9SKrishna Gudipati 	 */
1191f16a1750SMaggie Zhang 	if (fchs->d_id == bfa_hton3b(FC_FABRIC_PORT)) {
1192a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, pid);
1193a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_process_uf(fabric, fchs, len);
1194a36c61f9SKrishna Gudipati 		return;
1195a36c61f9SKrishna Gudipati 	}
1196a36c61f9SKrishna Gudipati 
1197a36c61f9SKrishna Gudipati 	if (fabric->bport.pid == pid) {
11985fbe25c7SJing Huang 		/*
1199a36c61f9SKrishna Gudipati 		 * All authentication frames should be routed to auth
1200a36c61f9SKrishna Gudipati 		 */
1201a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, els_cmd->els_code);
1202a36c61f9SKrishna Gudipati 		if (els_cmd->els_code == FC_ELS_AUTH) {
1203a36c61f9SKrishna Gudipati 			bfa_trc(fabric->fcs, els_cmd->els_code);
1204a36c61f9SKrishna Gudipati 			return;
1205a36c61f9SKrishna Gudipati 		}
1206a36c61f9SKrishna Gudipati 
1207a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
1208a36c61f9SKrishna Gudipati 		bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
1209a36c61f9SKrishna Gudipati 		return;
1210a36c61f9SKrishna Gudipati 	}
1211a36c61f9SKrishna Gudipati 
12125fbe25c7SJing Huang 	/*
1213a36c61f9SKrishna Gudipati 	 * look for a matching local port ID
1214a36c61f9SKrishna Gudipati 	 */
1215a36c61f9SKrishna Gudipati 	list_for_each(qe, &fabric->vport_q) {
1216a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1217a36c61f9SKrishna Gudipati 		if (vport->lport.pid == pid) {
1218a36c61f9SKrishna Gudipati 			bfa_fcs_lport_uf_recv(&vport->lport, fchs, len);
1219a36c61f9SKrishna Gudipati 			return;
1220a36c61f9SKrishna Gudipati 		}
1221a36c61f9SKrishna Gudipati 	}
1222a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, els_cmd->els_code);
1223a36c61f9SKrishna Gudipati 	bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
1224a36c61f9SKrishna Gudipati }
1225a36c61f9SKrishna Gudipati 
12265fbe25c7SJing Huang /*
1227a36c61f9SKrishna Gudipati  *		Unsolicited frames to be processed by fabric.
1228a36c61f9SKrishna Gudipati  */
1229a36c61f9SKrishna Gudipati static void
1230a36c61f9SKrishna Gudipati bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1231a36c61f9SKrishna Gudipati 			  u16 len)
1232a36c61f9SKrishna Gudipati {
1233a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1234a36c61f9SKrishna Gudipati 
1235a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, els_cmd->els_code);
1236a36c61f9SKrishna Gudipati 
1237a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
1238a36c61f9SKrishna Gudipati 	case FC_ELS_FLOGI:
1239a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_process_flogi(fabric, fchs, len);
1240a36c61f9SKrishna Gudipati 		break;
1241a36c61f9SKrishna Gudipati 
1242a36c61f9SKrishna Gudipati 	default:
1243a36c61f9SKrishna Gudipati 		/*
1244a36c61f9SKrishna Gudipati 		 * need to generate a LS_RJT
1245a36c61f9SKrishna Gudipati 		 */
1246a36c61f9SKrishna Gudipati 		break;
1247a36c61f9SKrishna Gudipati 	}
1248a36c61f9SKrishna Gudipati }
1249a36c61f9SKrishna Gudipati 
12505fbe25c7SJing Huang /*
1251a36c61f9SKrishna Gudipati  *	Process	incoming FLOGI
1252a36c61f9SKrishna Gudipati  */
1253a36c61f9SKrishna Gudipati static void
1254a36c61f9SKrishna Gudipati bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
1255a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
1256a36c61f9SKrishna Gudipati {
1257a36c61f9SKrishna Gudipati 	struct fc_logi_s *flogi = (struct fc_logi_s *) (fchs + 1);
1258a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *bport = &fabric->bport;
1259a36c61f9SKrishna Gudipati 
1260a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fchs->s_id);
1261a36c61f9SKrishna Gudipati 
1262a36c61f9SKrishna Gudipati 	fabric->stats.flogi_rcvd++;
1263a36c61f9SKrishna Gudipati 	/*
1264a36c61f9SKrishna Gudipati 	 * Check port type. It should be 0 = n-port.
1265a36c61f9SKrishna Gudipati 	 */
1266a36c61f9SKrishna Gudipati 	if (flogi->csp.port_type) {
1267a36c61f9SKrishna Gudipati 		/*
1268a36c61f9SKrishna Gudipati 		 * @todo: may need to send a LS_RJT
1269a36c61f9SKrishna Gudipati 		 */
1270a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, flogi->port_name);
1271a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rejected++;
1272a36c61f9SKrishna Gudipati 		return;
1273a36c61f9SKrishna Gudipati 	}
1274a36c61f9SKrishna Gudipati 
1275ba816ea8SJing Huang 	fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred);
1276be540a99SKrishna Gudipati 	fabric->lps->pr_bbscn = (be16_to_cpu(flogi->csp.rxsz) >> 12);
1277a36c61f9SKrishna Gudipati 	bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
1278a36c61f9SKrishna Gudipati 	bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
1279a36c61f9SKrishna Gudipati 
1280a36c61f9SKrishna Gudipati 	/*
1281a36c61f9SKrishna Gudipati 	 * Send a Flogi Acc
1282a36c61f9SKrishna Gudipati 	 */
1283a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_send_flogi_acc(fabric);
1284a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
1285a36c61f9SKrishna Gudipati }
1286a36c61f9SKrishna Gudipati 
1287a36c61f9SKrishna Gudipati static void
1288a36c61f9SKrishna Gudipati bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1289a36c61f9SKrishna Gudipati {
1290a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
1291a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
1292a36c61f9SKrishna Gudipati 	struct bfa_s	  *bfa = fabric->fcs->bfa;
1293a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1294a36c61f9SKrishna Gudipati 	u16	reqlen;
1295a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1296a36c61f9SKrishna Gudipati 
1297a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
12985fbe25c7SJing Huang 	/*
1299a36c61f9SKrishna Gudipati 	 * Do not expect this failure -- expect remote node to retry
1300a36c61f9SKrishna Gudipati 	 */
1301a36c61f9SKrishna Gudipati 	if (!fcxp)
1302a36c61f9SKrishna Gudipati 		return;
1303a36c61f9SKrishna Gudipati 
1304a36c61f9SKrishna Gudipati 	reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1305f16a1750SMaggie Zhang 				    bfa_hton3b(FC_FABRIC_PORT),
1306a36c61f9SKrishna Gudipati 				    n2n_port->reply_oxid, pcfg->pwwn,
1307a36c61f9SKrishna Gudipati 				    pcfg->nwwn,
1308a36c61f9SKrishna Gudipati 				    bfa_fcport_get_maxfrsize(bfa),
1309be540a99SKrishna Gudipati 				    bfa_fcport_get_rx_bbcredit(bfa),
1310be540a99SKrishna Gudipati 				    bfa_fcs_fabric_oper_bbscn(fabric));
1311a36c61f9SKrishna Gudipati 
13123fd45980SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->bfa_tag,
1313a36c61f9SKrishna Gudipati 		      BFA_FALSE, FC_CLASS_3,
1314a36c61f9SKrishna Gudipati 		      reqlen, &fchs, bfa_fcs_fabric_flogiacc_comp, fabric,
1315a36c61f9SKrishna Gudipati 		      FC_MAX_PDUSZ, 0);
1316a36c61f9SKrishna Gudipati }
1317a36c61f9SKrishna Gudipati 
13185fbe25c7SJing Huang /*
1319a36c61f9SKrishna Gudipati  *   Flogi Acc completion callback.
1320a36c61f9SKrishna Gudipati  */
1321a36c61f9SKrishna Gudipati static void
1322a36c61f9SKrishna Gudipati bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1323a36c61f9SKrishna Gudipati 			     bfa_status_t status, u32 rsp_len,
1324a36c61f9SKrishna Gudipati 			     u32 resid_len, struct fchs_s *rspfchs)
1325a36c61f9SKrishna Gudipati {
1326a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
1327a36c61f9SKrishna Gudipati 
1328a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, status);
1329a36c61f9SKrishna Gudipati }
1330a36c61f9SKrishna Gudipati 
13317826f304SKrishna Gudipati 
13327826f304SKrishna Gudipati /*
13337826f304SKrishna Gudipati  * Send AEN notification
13347826f304SKrishna Gudipati  */
13357826f304SKrishna Gudipati static void
13367826f304SKrishna Gudipati bfa_fcs_fabric_aen_post(struct bfa_fcs_lport_s *port,
13377826f304SKrishna Gudipati 			enum bfa_port_aen_event event)
13387826f304SKrishna Gudipati {
13397826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
13407826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
13417826f304SKrishna Gudipati 
13427826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
13437826f304SKrishna Gudipati 	if (!aen_entry)
13447826f304SKrishna Gudipati 		return;
13457826f304SKrishna Gudipati 
13467826f304SKrishna Gudipati 	aen_entry->aen_data.port.pwwn = bfa_fcs_lport_get_pwwn(port);
13477826f304SKrishna Gudipati 	aen_entry->aen_data.port.fwwn = bfa_fcs_lport_get_fabric_name(port);
13487826f304SKrishna Gudipati 
13497826f304SKrishna Gudipati 	/* Send the AEN notification */
13507826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
13517826f304SKrishna Gudipati 				  BFA_AEN_CAT_PORT, event);
13527826f304SKrishna Gudipati }
13537826f304SKrishna Gudipati 
1354a36c61f9SKrishna Gudipati /*
1355a36c61f9SKrishna Gudipati  *
1356a36c61f9SKrishna Gudipati  * @param[in] fabric - fabric
1357a36c61f9SKrishna Gudipati  * @param[in] wwn_t - new fabric name
1358a36c61f9SKrishna Gudipati  *
1359a36c61f9SKrishna Gudipati  * @return - none
1360a36c61f9SKrishna Gudipati  */
1361a36c61f9SKrishna Gudipati void
1362a36c61f9SKrishna Gudipati bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1363a36c61f9SKrishna Gudipati 			       wwn_t fabric_name)
1364a36c61f9SKrishna Gudipati {
1365a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
1366a36c61f9SKrishna Gudipati 	char	pwwn_ptr[BFA_STRING_32];
1367a36c61f9SKrishna Gudipati 	char	fwwn_ptr[BFA_STRING_32];
1368a36c61f9SKrishna Gudipati 
1369a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric_name);
1370a36c61f9SKrishna Gudipati 
1371a36c61f9SKrishna Gudipati 	if (fabric->fabric_name == 0) {
1372a36c61f9SKrishna Gudipati 		/*
1373a36c61f9SKrishna Gudipati 		 * With BRCD switches, we don't get Fabric Name in FLOGI.
1374a36c61f9SKrishna Gudipati 		 * Don't generate a fabric name change event in this case.
1375a36c61f9SKrishna Gudipati 		 */
1376a36c61f9SKrishna Gudipati 		fabric->fabric_name = fabric_name;
1377a36c61f9SKrishna Gudipati 	} else {
1378a36c61f9SKrishna Gudipati 		fabric->fabric_name = fabric_name;
1379a36c61f9SKrishna Gudipati 		wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport));
1380a36c61f9SKrishna Gudipati 		wwn2str(fwwn_ptr,
1381a36c61f9SKrishna Gudipati 			bfa_fcs_lport_get_fabric_name(&fabric->bport));
138288166242SJing Huang 		BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
1383a36c61f9SKrishna Gudipati 			"Base port WWN = %s Fabric WWN = %s\n",
1384a36c61f9SKrishna Gudipati 			pwwn_ptr, fwwn_ptr);
13857826f304SKrishna Gudipati 		bfa_fcs_fabric_aen_post(&fabric->bport,
13867826f304SKrishna Gudipati 				BFA_PORT_AEN_FABRIC_NAME_CHANGE);
1387a36c61f9SKrishna Gudipati 	}
1388a36c61f9SKrishna Gudipati }
1389a36c61f9SKrishna Gudipati 
13905fbe25c7SJing Huang /*
1391a36c61f9SKrishna Gudipati  *	Returns FCS vf structure for a given vf_id.
1392a36c61f9SKrishna Gudipati  *
1393a36c61f9SKrishna Gudipati  *	param[in]	vf_id - VF_ID
1394a36c61f9SKrishna Gudipati  *
1395a36c61f9SKrishna Gudipati  *	return
1396a36c61f9SKrishna Gudipati  *	If lookup succeeds, retuns fcs vf object, otherwise returns NULL
1397a36c61f9SKrishna Gudipati  */
1398a36c61f9SKrishna Gudipati bfa_fcs_vf_t   *
1399a36c61f9SKrishna Gudipati bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id)
1400a36c61f9SKrishna Gudipati {
1401a36c61f9SKrishna Gudipati 	bfa_trc(fcs, vf_id);
1402a36c61f9SKrishna Gudipati 	if (vf_id == FC_VF_ID_NULL)
1403a36c61f9SKrishna Gudipati 		return &fcs->fabric;
1404a36c61f9SKrishna Gudipati 
1405a36c61f9SKrishna Gudipati 	return NULL;
1406a36c61f9SKrishna Gudipati }
1407a36c61f9SKrishna Gudipati 
14085fbe25c7SJing Huang /*
1409b85daafeSKrishna Gudipati  *	Return the list of local logical ports present in the given VF.
1410b85daafeSKrishna Gudipati  *
1411b85daafeSKrishna Gudipati  *	@param[in]	vf	vf for which logical ports are returned
1412b85daafeSKrishna Gudipati  *	@param[out]	lpwwn	returned logical port wwn list
1413b85daafeSKrishna Gudipati  *	@param[in,out]	nlports in:size of lpwwn list;
1414b85daafeSKrishna Gudipati  *				out:total elements present,
1415b85daafeSKrishna Gudipati  *				actual elements returned is limited by the size
1416b85daafeSKrishna Gudipati  */
1417b85daafeSKrishna Gudipati void
1418b85daafeSKrishna Gudipati bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t lpwwn[], int *nlports)
1419b85daafeSKrishna Gudipati {
1420b85daafeSKrishna Gudipati 	struct list_head *qe;
1421b85daafeSKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1422b85daafeSKrishna Gudipati 	int	i = 0;
1423b85daafeSKrishna Gudipati 	struct bfa_fcs_s	*fcs;
1424b85daafeSKrishna Gudipati 
1425b85daafeSKrishna Gudipati 	if (vf == NULL || lpwwn == NULL || *nlports == 0)
1426b85daafeSKrishna Gudipati 		return;
1427b85daafeSKrishna Gudipati 
1428b85daafeSKrishna Gudipati 	fcs = vf->fcs;
1429b85daafeSKrishna Gudipati 
1430b85daafeSKrishna Gudipati 	bfa_trc(fcs, vf->vf_id);
1431b85daafeSKrishna Gudipati 	bfa_trc(fcs, (uint32_t) *nlports);
1432b85daafeSKrishna Gudipati 
1433b85daafeSKrishna Gudipati 	lpwwn[i++] = vf->bport.port_cfg.pwwn;
1434b85daafeSKrishna Gudipati 
1435b85daafeSKrishna Gudipati 	list_for_each(qe, &vf->vport_q) {
1436b85daafeSKrishna Gudipati 		if (i >= *nlports)
1437b85daafeSKrishna Gudipati 			break;
1438b85daafeSKrishna Gudipati 
1439b85daafeSKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1440b85daafeSKrishna Gudipati 		lpwwn[i++] = vport->lport.port_cfg.pwwn;
1441b85daafeSKrishna Gudipati 	}
1442b85daafeSKrishna Gudipati 
1443b85daafeSKrishna Gudipati 	bfa_trc(fcs, i);
1444b85daafeSKrishna Gudipati 	*nlports = i;
1445b85daafeSKrishna Gudipati }
1446b85daafeSKrishna Gudipati 
1447b85daafeSKrishna Gudipati /*
1448a36c61f9SKrishna Gudipati  * BFA FCS PPORT ( physical port)
1449a36c61f9SKrishna Gudipati  */
1450a36c61f9SKrishna Gudipati static void
1451a36c61f9SKrishna Gudipati bfa_fcs_port_event_handler(void *cbarg, enum bfa_port_linkstate event)
1452a36c61f9SKrishna Gudipati {
1453a36c61f9SKrishna Gudipati 	struct bfa_fcs_s      *fcs = cbarg;
1454a36c61f9SKrishna Gudipati 
1455a36c61f9SKrishna Gudipati 	bfa_trc(fcs, event);
1456a36c61f9SKrishna Gudipati 
1457a36c61f9SKrishna Gudipati 	switch (event) {
1458a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKUP:
1459a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_link_up(&fcs->fabric);
1460a36c61f9SKrishna Gudipati 		break;
1461a36c61f9SKrishna Gudipati 
1462a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKDOWN:
1463a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_link_down(&fcs->fabric);
1464a36c61f9SKrishna Gudipati 		break;
1465a36c61f9SKrishna Gudipati 
1466a36c61f9SKrishna Gudipati 	default:
1467d4b671c5SJing Huang 		WARN_ON(1);
1468a36c61f9SKrishna Gudipati 	}
1469a36c61f9SKrishna Gudipati }
1470a36c61f9SKrishna Gudipati 
1471a36c61f9SKrishna Gudipati void
1472a36c61f9SKrishna Gudipati bfa_fcs_port_attach(struct bfa_fcs_s *fcs)
1473a36c61f9SKrishna Gudipati {
1474a36c61f9SKrishna Gudipati 	bfa_fcport_event_register(fcs->bfa, bfa_fcs_port_event_handler, fcs);
1475a36c61f9SKrishna Gudipati }
1476a36c61f9SKrishna Gudipati 
14775fbe25c7SJing Huang /*
1478a36c61f9SKrishna Gudipati  * BFA FCS UF ( Unsolicited Frames)
1479a36c61f9SKrishna Gudipati  */
1480a36c61f9SKrishna Gudipati 
14815fbe25c7SJing Huang /*
1482a36c61f9SKrishna Gudipati  *		BFA callback for unsolicited frame receive handler.
1483a36c61f9SKrishna Gudipati  *
1484a36c61f9SKrishna Gudipati  * @param[in]		cbarg		callback arg for receive handler
1485a36c61f9SKrishna Gudipati  * @param[in]		uf		unsolicited frame descriptor
1486a36c61f9SKrishna Gudipati  *
1487a36c61f9SKrishna Gudipati  * @return None
1488a36c61f9SKrishna Gudipati  */
1489a36c61f9SKrishna Gudipati static void
1490a36c61f9SKrishna Gudipati bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
1491a36c61f9SKrishna Gudipati {
1492a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs = (struct bfa_fcs_s *) cbarg;
1493a36c61f9SKrishna Gudipati 	struct fchs_s	*fchs = bfa_uf_get_frmbuf(uf);
1494a36c61f9SKrishna Gudipati 	u16	len = bfa_uf_get_frmlen(uf);
1495a36c61f9SKrishna Gudipati 	struct fc_vft_s *vft;
1496a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1497a36c61f9SKrishna Gudipati 
14985fbe25c7SJing Huang 	/*
1499a36c61f9SKrishna Gudipati 	 * check for VFT header
1500a36c61f9SKrishna Gudipati 	 */
1501a36c61f9SKrishna Gudipati 	if (fchs->routing == FC_RTG_EXT_HDR &&
1502a36c61f9SKrishna Gudipati 	    fchs->cat_info == FC_CAT_VFT_HDR) {
1503a36c61f9SKrishna Gudipati 		bfa_stats(fcs, uf.tagged);
1504a36c61f9SKrishna Gudipati 		vft = bfa_uf_get_frmbuf(uf);
1505a36c61f9SKrishna Gudipati 		if (fcs->port_vfid == vft->vf_id)
1506a36c61f9SKrishna Gudipati 			fabric = &fcs->fabric;
1507a36c61f9SKrishna Gudipati 		else
1508a36c61f9SKrishna Gudipati 			fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id);
1509a36c61f9SKrishna Gudipati 
15105fbe25c7SJing Huang 		/*
1511a36c61f9SKrishna Gudipati 		 * drop frame if vfid is unknown
1512a36c61f9SKrishna Gudipati 		 */
1513a36c61f9SKrishna Gudipati 		if (!fabric) {
1514d4b671c5SJing Huang 			WARN_ON(1);
1515a36c61f9SKrishna Gudipati 			bfa_stats(fcs, uf.vfid_unknown);
1516a36c61f9SKrishna Gudipati 			bfa_uf_free(uf);
1517a36c61f9SKrishna Gudipati 			return;
1518a36c61f9SKrishna Gudipati 		}
1519a36c61f9SKrishna Gudipati 
15205fbe25c7SJing Huang 		/*
1521a36c61f9SKrishna Gudipati 		 * skip vft header
1522a36c61f9SKrishna Gudipati 		 */
1523a36c61f9SKrishna Gudipati 		fchs = (struct fchs_s *) (vft + 1);
1524a36c61f9SKrishna Gudipati 		len -= sizeof(struct fc_vft_s);
1525a36c61f9SKrishna Gudipati 
1526a36c61f9SKrishna Gudipati 		bfa_trc(fcs, vft->vf_id);
1527a36c61f9SKrishna Gudipati 	} else {
1528a36c61f9SKrishna Gudipati 		bfa_stats(fcs, uf.untagged);
1529a36c61f9SKrishna Gudipati 		fabric = &fcs->fabric;
1530a36c61f9SKrishna Gudipati 	}
1531a36c61f9SKrishna Gudipati 
1532a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[0]);
1533a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[1]);
1534a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[2]);
1535a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[3]);
1536a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[4]);
1537a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[5]);
1538a36c61f9SKrishna Gudipati 	bfa_trc(fcs, len);
1539a36c61f9SKrishna Gudipati 
1540a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_uf_recv(fabric, fchs, len);
1541a36c61f9SKrishna Gudipati 	bfa_uf_free(uf);
1542a36c61f9SKrishna Gudipati }
1543a36c61f9SKrishna Gudipati 
1544a36c61f9SKrishna Gudipati void
1545a36c61f9SKrishna Gudipati bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
1546a36c61f9SKrishna Gudipati {
1547a36c61f9SKrishna Gudipati 	bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
1548a36c61f9SKrishna Gudipati }
1549