xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs.c (revision 25985edc)
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"
23a36c61f9SKrishna Gudipati #include "bfa_fcs.h"
24a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h"
25a36c61f9SKrishna Gudipati 
26a36c61f9SKrishna Gudipati BFA_TRC_FILE(FCS, FCS);
277725ccfdSJing Huang 
285fbe25c7SJing Huang /*
297725ccfdSJing Huang  * FCS sub-modules
307725ccfdSJing Huang  */
317725ccfdSJing Huang struct bfa_fcs_mod_s {
3282794a2eSKrishna Gudipati 	void		(*attach) (struct bfa_fcs_s *fcs);
337725ccfdSJing Huang 	void		(*modinit) (struct bfa_fcs_s *fcs);
347725ccfdSJing Huang 	void		(*modexit) (struct bfa_fcs_s *fcs);
357725ccfdSJing Huang };
367725ccfdSJing Huang 
377725ccfdSJing Huang #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
387725ccfdSJing Huang 
397725ccfdSJing Huang static struct bfa_fcs_mod_s fcs_modules[] = {
40a36c61f9SKrishna Gudipati 	{ bfa_fcs_port_attach, NULL, NULL },
4182794a2eSKrishna Gudipati 	{ bfa_fcs_uf_attach, NULL, NULL },
4282794a2eSKrishna Gudipati 	{ bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
4382794a2eSKrishna Gudipati 	  bfa_fcs_fabric_modexit },
447725ccfdSJing Huang };
457725ccfdSJing Huang 
465fbe25c7SJing Huang /*
477725ccfdSJing Huang  *  fcs_api BFA FCS API
487725ccfdSJing Huang  */
497725ccfdSJing Huang 
507725ccfdSJing Huang static void
517725ccfdSJing Huang bfa_fcs_exit_comp(void *fcs_cbarg)
527725ccfdSJing Huang {
537725ccfdSJing Huang 	struct bfa_fcs_s      *fcs = fcs_cbarg;
547725ccfdSJing Huang 	struct bfad_s         *bfad = fcs->bfad;
557725ccfdSJing Huang 
567725ccfdSJing Huang 	complete(&bfad->comp);
577725ccfdSJing Huang }
587725ccfdSJing Huang 
597725ccfdSJing Huang 
607725ccfdSJing Huang 
615fbe25c7SJing Huang /*
627725ccfdSJing Huang  *  fcs_api BFA FCS API
637725ccfdSJing Huang  */
647725ccfdSJing Huang 
655fbe25c7SJing Huang /*
6682794a2eSKrishna Gudipati  * fcs attach -- called once to initialize data structures at driver attach time
677725ccfdSJing Huang  */
687725ccfdSJing Huang void
6982794a2eSKrishna Gudipati bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
707725ccfdSJing Huang 	       bfa_boolean_t min_cfg)
717725ccfdSJing Huang {
727725ccfdSJing Huang 	int		i;
737725ccfdSJing Huang 	struct bfa_fcs_mod_s  *mod;
747725ccfdSJing Huang 
757725ccfdSJing Huang 	fcs->bfa = bfa;
767725ccfdSJing Huang 	fcs->bfad = bfad;
777725ccfdSJing Huang 	fcs->min_cfg = min_cfg;
787725ccfdSJing Huang 
79f7f73812SMaggie Zhang 	bfa->fcs = BFA_TRUE;
807725ccfdSJing Huang 	fcbuild_init();
817725ccfdSJing Huang 
82a36c61f9SKrishna Gudipati 	for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
837725ccfdSJing Huang 		mod = &fcs_modules[i];
8482794a2eSKrishna Gudipati 		if (mod->attach)
8582794a2eSKrishna Gudipati 			mod->attach(fcs);
8682794a2eSKrishna Gudipati 	}
8782794a2eSKrishna Gudipati }
8882794a2eSKrishna Gudipati 
895fbe25c7SJing Huang /*
9082794a2eSKrishna Gudipati  * fcs initialization, called once after bfa initialization is complete
9182794a2eSKrishna Gudipati  */
9282794a2eSKrishna Gudipati void
9382794a2eSKrishna Gudipati bfa_fcs_init(struct bfa_fcs_s *fcs)
9482794a2eSKrishna Gudipati {
95d9883548SJing Huang 	int		i, npbc_vports;
9682794a2eSKrishna Gudipati 	struct bfa_fcs_mod_s  *mod;
97d9883548SJing Huang 	struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];
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 	}
104d9883548SJing Huang 	/* Initialize pbc vports */
105d9883548SJing Huang 	if (!fcs->min_cfg) {
106d9883548SJing Huang 		npbc_vports =
107d9883548SJing Huang 		    bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
108d9883548SJing Huang 		for (i = 0; i < npbc_vports; i++)
109d9883548SJing Huang 			bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
110d9883548SJing Huang 	}
1117725ccfdSJing Huang }
1127725ccfdSJing Huang 
1137725ccfdSJing Huang 
1145fbe25c7SJing Huang /*
115a36c61f9SKrishna Gudipati  *	brief
1167725ccfdSJing Huang  *		FCS driver details initialization.
1177725ccfdSJing Huang  *
1187725ccfdSJing Huang  *	param[in]		fcs		FCS instance
1197725ccfdSJing Huang  *	param[in]		driver_info	Driver Details
1207725ccfdSJing Huang  *
1217725ccfdSJing Huang  *	return None
1227725ccfdSJing Huang  */
1237725ccfdSJing Huang void
1247725ccfdSJing Huang bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
1257725ccfdSJing Huang 			struct bfa_fcs_driver_info_s *driver_info)
1267725ccfdSJing Huang {
1277725ccfdSJing Huang 
1287725ccfdSJing Huang 	fcs->driver_info = *driver_info;
1297725ccfdSJing Huang 
1307725ccfdSJing Huang 	bfa_fcs_fabric_psymb_init(&fcs->fabric);
1317725ccfdSJing Huang }
1327725ccfdSJing Huang 
1335fbe25c7SJing Huang /*
134a36c61f9SKrishna Gudipati  *	brief
1357725ccfdSJing Huang  *		FCS instance cleanup and exit.
1367725ccfdSJing Huang  *
1377725ccfdSJing Huang  *	param[in]		fcs			FCS instance
1387725ccfdSJing Huang  *	return None
1397725ccfdSJing Huang  */
1407725ccfdSJing Huang void
1417725ccfdSJing Huang bfa_fcs_exit(struct bfa_fcs_s *fcs)
1427725ccfdSJing Huang {
1437725ccfdSJing Huang 	struct bfa_fcs_mod_s  *mod;
144a36c61f9SKrishna Gudipati 	int		nmods, i;
1457725ccfdSJing Huang 
1467725ccfdSJing Huang 	bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
1477725ccfdSJing Huang 
148a36c61f9SKrishna Gudipati 	nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
149a36c61f9SKrishna Gudipati 
150a36c61f9SKrishna Gudipati 	for (i = 0; i < nmods; i++) {
1517725ccfdSJing Huang 
1527725ccfdSJing Huang 		mod = &fcs_modules[i];
15382794a2eSKrishna Gudipati 		if (mod->modexit) {
15482794a2eSKrishna Gudipati 			bfa_wc_up(&fcs->wc);
1557725ccfdSJing Huang 			mod->modexit(fcs);
1567725ccfdSJing Huang 		}
15782794a2eSKrishna Gudipati 	}
1587725ccfdSJing Huang 
1597725ccfdSJing Huang 	bfa_wc_wait(&fcs->wc);
1607725ccfdSJing Huang }
1617725ccfdSJing Huang 
1627725ccfdSJing Huang 
1635fbe25c7SJing Huang /*
164a36c61f9SKrishna Gudipati  * Fabric module implementation.
165a36c61f9SKrishna Gudipati  */
1667725ccfdSJing Huang 
167a36c61f9SKrishna Gudipati #define BFA_FCS_FABRIC_RETRY_DELAY	(2000)	/* Milliseconds */
168a36c61f9SKrishna Gudipati #define BFA_FCS_FABRIC_CLEANUP_DELAY	(10000)	/* Milliseconds */
169a36c61f9SKrishna Gudipati 
170a36c61f9SKrishna Gudipati #define bfa_fcs_fabric_set_opertype(__fabric) do {			\
171a36c61f9SKrishna Gudipati 		if (bfa_fcport_get_topology((__fabric)->fcs->bfa)	\
172a36c61f9SKrishna Gudipati 		    == BFA_PORT_TOPOLOGY_P2P)				\
173a36c61f9SKrishna Gudipati 			(__fabric)->oper_type = BFA_PORT_TYPE_NPORT;	\
174a36c61f9SKrishna Gudipati 		else							\
175a36c61f9SKrishna Gudipati 			(__fabric)->oper_type = BFA_PORT_TYPE_NLPORT;	\
176a36c61f9SKrishna Gudipati } while (0)
177a36c61f9SKrishna Gudipati 
178a36c61f9SKrishna Gudipati /*
179a36c61f9SKrishna Gudipati  * forward declarations
180a36c61f9SKrishna Gudipati  */
181a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
182a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
183a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
184a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
185a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delay(void *cbarg);
186a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
187a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delete_comp(void *cbarg);
188a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
189a36c61f9SKrishna Gudipati 				      struct fchs_s *fchs, u16 len);
190a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
191a36c61f9SKrishna Gudipati 					 struct fchs_s *fchs, u16 len);
192a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
193a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
194a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp, void *cbarg,
195a36c61f9SKrishna Gudipati 					 bfa_status_t status,
196a36c61f9SKrishna Gudipati 					 u32 rsp_len,
197a36c61f9SKrishna Gudipati 					 u32 resid_len,
198a36c61f9SKrishna Gudipati 					 struct fchs_s *rspfchs);
199a36c61f9SKrishna Gudipati 
200a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
201a36c61f9SKrishna Gudipati 					 enum bfa_fcs_fabric_event event);
202a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
203a36c61f9SKrishna Gudipati 					  enum bfa_fcs_fabric_event event);
204a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
205a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
206a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
207a36c61f9SKrishna Gudipati 					enum bfa_fcs_fabric_event event);
208a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
209a36c61f9SKrishna Gudipati 					      enum bfa_fcs_fabric_event event);
210a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
211a36c61f9SKrishna Gudipati 				       enum bfa_fcs_fabric_event event);
212a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
213a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
214a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
215a36c61f9SKrishna Gudipati 				       enum bfa_fcs_fabric_event event);
216a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
217a36c61f9SKrishna Gudipati 					    enum bfa_fcs_fabric_event event);
218a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
219a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
220a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
221a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
2225fbe25c7SJing Huang /*
223a36c61f9SKrishna Gudipati  *   Beginning state before fabric creation.
224a36c61f9SKrishna Gudipati  */
225a36c61f9SKrishna Gudipati static void
226a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
227a36c61f9SKrishna Gudipati 			 enum bfa_fcs_fabric_event event)
228a36c61f9SKrishna Gudipati {
229a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
230a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
231a36c61f9SKrishna Gudipati 
232a36c61f9SKrishna Gudipati 	switch (event) {
233a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CREATE:
234a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
235a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_init(fabric);
236a36c61f9SKrishna Gudipati 		bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
237a36c61f9SKrishna Gudipati 		break;
238a36c61f9SKrishna Gudipati 
239a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
240a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
241a36c61f9SKrishna Gudipati 		break;
242a36c61f9SKrishna Gudipati 
243a36c61f9SKrishna Gudipati 	default:
244a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
245a36c61f9SKrishna Gudipati 	}
246a36c61f9SKrishna Gudipati }
247a36c61f9SKrishna Gudipati 
2485fbe25c7SJing Huang /*
249a36c61f9SKrishna Gudipati  *   Beginning state before fabric creation.
250a36c61f9SKrishna Gudipati  */
251a36c61f9SKrishna Gudipati static void
252a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
253a36c61f9SKrishna Gudipati 			  enum bfa_fcs_fabric_event event)
254a36c61f9SKrishna Gudipati {
255a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
256a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
257a36c61f9SKrishna Gudipati 
258a36c61f9SKrishna Gudipati 	switch (event) {
259a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_START:
260a36c61f9SKrishna Gudipati 		if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
261a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
262a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_login(fabric);
263a36c61f9SKrishna Gudipati 		} else
264a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
265a36c61f9SKrishna Gudipati 		break;
266a36c61f9SKrishna Gudipati 
267a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
268a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
269a36c61f9SKrishna Gudipati 		break;
270a36c61f9SKrishna Gudipati 
271a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
272a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
273f7f73812SMaggie Zhang 		bfa_wc_down(&fabric->fcs->wc);
274a36c61f9SKrishna Gudipati 		break;
275a36c61f9SKrishna Gudipati 
276a36c61f9SKrishna Gudipati 	default:
277a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
278a36c61f9SKrishna Gudipati 	}
279a36c61f9SKrishna Gudipati }
280a36c61f9SKrishna Gudipati 
2815fbe25c7SJing Huang /*
282a36c61f9SKrishna Gudipati  *   Link is down, awaiting LINK UP event from port. This is also the
283a36c61f9SKrishna Gudipati  *   first state at fabric creation.
284a36c61f9SKrishna Gudipati  */
285a36c61f9SKrishna Gudipati static void
286a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
287a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
288a36c61f9SKrishna Gudipati {
289a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
290a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
291a36c61f9SKrishna Gudipati 
292a36c61f9SKrishna Gudipati 	switch (event) {
293a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
294a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
295a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_login(fabric);
296a36c61f9SKrishna Gudipati 		break;
297a36c61f9SKrishna Gudipati 
298a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
299a36c61f9SKrishna Gudipati 		break;
300a36c61f9SKrishna Gudipati 
301a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
302a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
303a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
304a36c61f9SKrishna Gudipati 		break;
305a36c61f9SKrishna Gudipati 
306a36c61f9SKrishna Gudipati 	default:
307a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
308a36c61f9SKrishna Gudipati 	}
309a36c61f9SKrishna Gudipati }
310a36c61f9SKrishna Gudipati 
3115fbe25c7SJing Huang /*
312a36c61f9SKrishna Gudipati  *   FLOGI is in progress, awaiting FLOGI reply.
313a36c61f9SKrishna Gudipati  */
314a36c61f9SKrishna Gudipati static void
315a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
316a36c61f9SKrishna Gudipati 			enum bfa_fcs_fabric_event event)
317a36c61f9SKrishna Gudipati {
318a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
319a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
320a36c61f9SKrishna Gudipati 
321a36c61f9SKrishna Gudipati 	switch (event) {
322a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CONT_OP:
323a36c61f9SKrishna Gudipati 
324a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
325a36c61f9SKrishna Gudipati 					   fabric->bb_credit);
326a36c61f9SKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
327a36c61f9SKrishna Gudipati 
328a36c61f9SKrishna Gudipati 		if (fabric->auth_reqd && fabric->is_auth) {
329a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth);
330a36c61f9SKrishna Gudipati 			bfa_trc(fabric->fcs, event);
331a36c61f9SKrishna Gudipati 		} else {
332a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
333a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_notify_online(fabric);
334a36c61f9SKrishna Gudipati 		}
335a36c61f9SKrishna Gudipati 		break;
336a36c61f9SKrishna Gudipati 
337a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
338a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry);
339a36c61f9SKrishna Gudipati 		bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer,
340a36c61f9SKrishna Gudipati 				bfa_fcs_fabric_delay, fabric,
341a36c61f9SKrishna Gudipati 				BFA_FCS_FABRIC_RETRY_DELAY);
342a36c61f9SKrishna Gudipati 		break;
343a36c61f9SKrishna Gudipati 
344a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LOOPBACK:
345a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
346f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
347a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_set_opertype(fabric);
348a36c61f9SKrishna Gudipati 		break;
349a36c61f9SKrishna Gudipati 
350a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
351a36c61f9SKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_N2N;
352a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
353a36c61f9SKrishna Gudipati 					   fabric->bb_credit);
354a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_online(fabric);
355a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
356a36c61f9SKrishna Gudipati 		break;
357a36c61f9SKrishna Gudipati 
358a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
359a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
360f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
361a36c61f9SKrishna Gudipati 		break;
362a36c61f9SKrishna Gudipati 
363a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
364a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
365f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
366a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
367a36c61f9SKrishna Gudipati 		break;
368a36c61f9SKrishna Gudipati 
369a36c61f9SKrishna Gudipati 	default:
370a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
371a36c61f9SKrishna Gudipati 	}
372a36c61f9SKrishna Gudipati }
373a36c61f9SKrishna Gudipati 
374a36c61f9SKrishna Gudipati 
375a36c61f9SKrishna Gudipati static void
376a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
377a36c61f9SKrishna Gudipati 			      enum bfa_fcs_fabric_event event)
378a36c61f9SKrishna Gudipati {
379a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
380a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
381a36c61f9SKrishna Gudipati 
382a36c61f9SKrishna Gudipati 	switch (event) {
383a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELAYED:
384a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
385a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_login(fabric);
386a36c61f9SKrishna Gudipati 		break;
387a36c61f9SKrishna Gudipati 
388a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
389a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
390a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fabric->delay_timer);
391a36c61f9SKrishna Gudipati 		break;
392a36c61f9SKrishna Gudipati 
393a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
394a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
395a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fabric->delay_timer);
396a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
397a36c61f9SKrishna Gudipati 		break;
398a36c61f9SKrishna Gudipati 
399a36c61f9SKrishna Gudipati 	default:
400a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
401a36c61f9SKrishna Gudipati 	}
402a36c61f9SKrishna Gudipati }
403a36c61f9SKrishna Gudipati 
4045fbe25c7SJing Huang /*
405a36c61f9SKrishna Gudipati  *   Authentication is in progress, awaiting authentication results.
406a36c61f9SKrishna Gudipati  */
407a36c61f9SKrishna Gudipati static void
408a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
409a36c61f9SKrishna Gudipati 		       enum bfa_fcs_fabric_event event)
410a36c61f9SKrishna Gudipati {
411a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
412a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
413a36c61f9SKrishna Gudipati 
414a36c61f9SKrishna Gudipati 	switch (event) {
415a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_FAILED:
416a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
417f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
418a36c61f9SKrishna Gudipati 		break;
419a36c61f9SKrishna Gudipati 
420a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
421a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
422a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_online(fabric);
423a36c61f9SKrishna Gudipati 		break;
424a36c61f9SKrishna Gudipati 
425a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_PERF_EVFP:
426a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp);
427a36c61f9SKrishna Gudipati 		break;
428a36c61f9SKrishna Gudipati 
429a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
430a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
431f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
432a36c61f9SKrishna Gudipati 		break;
433a36c61f9SKrishna Gudipati 
434a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
435a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
436a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
437a36c61f9SKrishna Gudipati 		break;
438a36c61f9SKrishna Gudipati 
439a36c61f9SKrishna Gudipati 	default:
440a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
441a36c61f9SKrishna Gudipati 	}
442a36c61f9SKrishna Gudipati }
443a36c61f9SKrishna Gudipati 
4445fbe25c7SJing Huang /*
445a36c61f9SKrishna Gudipati  *   Authentication failed
446a36c61f9SKrishna Gudipati  */
447f7f73812SMaggie Zhang void
448a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
449a36c61f9SKrishna Gudipati 			      enum bfa_fcs_fabric_event event)
450a36c61f9SKrishna Gudipati {
451a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
452a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
453a36c61f9SKrishna Gudipati 
454a36c61f9SKrishna Gudipati 	switch (event) {
455a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
456a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
457a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
458a36c61f9SKrishna Gudipati 		break;
459a36c61f9SKrishna Gudipati 
460a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
461a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
462a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
463a36c61f9SKrishna Gudipati 		break;
464a36c61f9SKrishna Gudipati 
465a36c61f9SKrishna Gudipati 	default:
466a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
467a36c61f9SKrishna Gudipati 	}
468a36c61f9SKrishna Gudipati }
469a36c61f9SKrishna Gudipati 
4705fbe25c7SJing Huang /*
471a36c61f9SKrishna Gudipati  *   Port is in loopback mode.
472a36c61f9SKrishna Gudipati  */
473f7f73812SMaggie Zhang void
474a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
475a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
476a36c61f9SKrishna Gudipati {
477a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
478a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
479a36c61f9SKrishna Gudipati 
480a36c61f9SKrishna Gudipati 	switch (event) {
481a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
482a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
483a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
484a36c61f9SKrishna Gudipati 		break;
485a36c61f9SKrishna Gudipati 
486a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
487a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
488a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
489a36c61f9SKrishna Gudipati 		break;
490a36c61f9SKrishna Gudipati 
491a36c61f9SKrishna Gudipati 	default:
492a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
493a36c61f9SKrishna Gudipati 	}
494a36c61f9SKrishna Gudipati }
495a36c61f9SKrishna Gudipati 
4965fbe25c7SJing Huang /*
497a36c61f9SKrishna Gudipati  *   There is no attached fabric - private loop or NPort-to-NPort topology.
498a36c61f9SKrishna Gudipati  */
499a36c61f9SKrishna Gudipati static void
500a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
501a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
502a36c61f9SKrishna Gudipati {
503a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
504a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
505a36c61f9SKrishna Gudipati 
506a36c61f9SKrishna Gudipati 	switch (event) {
507a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
508a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
509f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
510a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
511a36c61f9SKrishna Gudipati 		break;
512a36c61f9SKrishna Gudipati 
513a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
514a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
515a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
516a36c61f9SKrishna Gudipati 		break;
517a36c61f9SKrishna Gudipati 
518a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
519a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, fabric->bb_credit);
520a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
521a36c61f9SKrishna Gudipati 					   fabric->bb_credit);
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  *   Fabric is online - normal operating state.
531a36c61f9SKrishna Gudipati  */
532f7f73812SMaggie Zhang void
533a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_online(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_AUTH_FAILED:
552a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
553f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
554a36c61f9SKrishna Gudipati 		break;
555a36c61f9SKrishna Gudipati 
556a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
557a36c61f9SKrishna Gudipati 		break;
558a36c61f9SKrishna Gudipati 
559a36c61f9SKrishna Gudipati 	default:
560a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
561a36c61f9SKrishna Gudipati 	}
562a36c61f9SKrishna Gudipati }
563a36c61f9SKrishna Gudipati 
5645fbe25c7SJing Huang /*
565a36c61f9SKrishna Gudipati  *   Exchanging virtual fabric parameters.
566a36c61f9SKrishna Gudipati  */
567a36c61f9SKrishna Gudipati static void
568a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
569a36c61f9SKrishna Gudipati 		       enum bfa_fcs_fabric_event event)
570a36c61f9SKrishna Gudipati {
571a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
572a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
573a36c61f9SKrishna Gudipati 
574a36c61f9SKrishna Gudipati 	switch (event) {
575a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CONT_OP:
576a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done);
577a36c61f9SKrishna Gudipati 		break;
578a36c61f9SKrishna Gudipati 
579a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_ISOLATE:
580a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated);
581a36c61f9SKrishna Gudipati 		break;
582a36c61f9SKrishna Gudipati 
583a36c61f9SKrishna Gudipati 	default:
584a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
585a36c61f9SKrishna Gudipati 	}
586a36c61f9SKrishna Gudipati }
587a36c61f9SKrishna Gudipati 
5885fbe25c7SJing Huang /*
589a36c61f9SKrishna Gudipati  *   EVFP exchange complete and VFT tagging is enabled.
590a36c61f9SKrishna Gudipati  */
591a36c61f9SKrishna Gudipati static void
592a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
593a36c61f9SKrishna Gudipati 			    enum bfa_fcs_fabric_event event)
594a36c61f9SKrishna Gudipati {
595a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
596a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
597a36c61f9SKrishna Gudipati }
598a36c61f9SKrishna Gudipati 
5995fbe25c7SJing Huang /*
600a36c61f9SKrishna Gudipati  *   Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
601a36c61f9SKrishna Gudipati  */
602a36c61f9SKrishna Gudipati static void
603a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
604a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
605a36c61f9SKrishna Gudipati {
606a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
607a36c61f9SKrishna Gudipati 	char	pwwn_ptr[BFA_STRING_32];
608a36c61f9SKrishna Gudipati 
609a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
610a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
611a36c61f9SKrishna Gudipati 	wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn);
612a36c61f9SKrishna Gudipati 
61388166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
614a36c61f9SKrishna Gudipati 		"Port is isolated due to VF_ID mismatch. "
615a36c61f9SKrishna Gudipati 		"PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.",
616a36c61f9SKrishna Gudipati 		pwwn_ptr, fabric->fcs->port_vfid,
617a36c61f9SKrishna Gudipati 		fabric->event_arg.swp_vfid);
618a36c61f9SKrishna Gudipati }
619a36c61f9SKrishna Gudipati 
6205fbe25c7SJing Huang /*
621a36c61f9SKrishna Gudipati  *   Fabric is being deleted, awaiting vport delete completions.
622a36c61f9SKrishna Gudipati  */
623a36c61f9SKrishna Gudipati static void
624a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
625a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
626a36c61f9SKrishna Gudipati {
627a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
628a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
629a36c61f9SKrishna Gudipati 
630a36c61f9SKrishna Gudipati 	switch (event) {
631a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELCOMP:
632a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
633f7f73812SMaggie Zhang 		bfa_wc_down(&fabric->fcs->wc);
634a36c61f9SKrishna Gudipati 		break;
635a36c61f9SKrishna Gudipati 
636a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
637a36c61f9SKrishna Gudipati 		break;
638a36c61f9SKrishna Gudipati 
639a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
640a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
641a36c61f9SKrishna Gudipati 		break;
642a36c61f9SKrishna Gudipati 
643a36c61f9SKrishna Gudipati 	default:
644a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
645a36c61f9SKrishna Gudipati 	}
646a36c61f9SKrishna Gudipati }
647a36c61f9SKrishna Gudipati 
648a36c61f9SKrishna Gudipati 
649a36c61f9SKrishna Gudipati 
6505fbe25c7SJing Huang /*
651a36c61f9SKrishna Gudipati  *  fcs_fabric_private fabric private functions
652a36c61f9SKrishna Gudipati  */
653a36c61f9SKrishna Gudipati 
654a36c61f9SKrishna Gudipati static void
655a36c61f9SKrishna Gudipati bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
656a36c61f9SKrishna Gudipati {
657a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
658a36c61f9SKrishna Gudipati 
659a36c61f9SKrishna Gudipati 	port_cfg->roles = BFA_LPORT_ROLE_FCP_IM;
660f7f73812SMaggie Zhang 	port_cfg->nwwn = fabric->fcs->bfa->ioc.attr->nwwn;
661f7f73812SMaggie Zhang 	port_cfg->pwwn = fabric->fcs->bfa->ioc.attr->pwwn;
662a36c61f9SKrishna Gudipati }
663a36c61f9SKrishna Gudipati 
6645fbe25c7SJing Huang /*
665a36c61f9SKrishna Gudipati  * Port Symbolic Name Creation for base port.
666a36c61f9SKrishna Gudipati  */
667a36c61f9SKrishna Gudipati void
668a36c61f9SKrishna Gudipati bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
669a36c61f9SKrishna Gudipati {
670a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
671a36c61f9SKrishna Gudipati 	char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
672a36c61f9SKrishna Gudipati 	struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
673a36c61f9SKrishna Gudipati 
674a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
675a36c61f9SKrishna Gudipati 
676a36c61f9SKrishna Gudipati 	/* Model name/number */
677a36c61f9SKrishna Gudipati 	strncpy((char *)&port_cfg->sym_name, model,
678a36c61f9SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
679a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
680a36c61f9SKrishna Gudipati 		sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
681a36c61f9SKrishna Gudipati 
682a36c61f9SKrishna Gudipati 	/* Driver Version */
683a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
684a36c61f9SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
685a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
686a36c61f9SKrishna Gudipati 		sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
687a36c61f9SKrishna Gudipati 
688a36c61f9SKrishna Gudipati 	/* Host machine name */
689a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name,
690a36c61f9SKrishna Gudipati 		(char *)driver_info->host_machine_name,
691a36c61f9SKrishna Gudipati 		BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
692a36c61f9SKrishna Gudipati 	strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
693a36c61f9SKrishna Gudipati 		sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
694a36c61f9SKrishna Gudipati 
695a36c61f9SKrishna Gudipati 	/*
696a36c61f9SKrishna Gudipati 	 * Host OS Info :
697a36c61f9SKrishna Gudipati 	 * If OS Patch Info is not there, do not truncate any bytes from the
698a36c61f9SKrishna Gudipati 	 * OS name string and instead copy the entire OS info string (64 bytes).
699a36c61f9SKrishna Gudipati 	 */
700a36c61f9SKrishna Gudipati 	if (driver_info->host_os_patch[0] == '\0') {
701a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
702a36c61f9SKrishna Gudipati 			(char *)driver_info->host_os_name,
703a36c61f9SKrishna Gudipati 			BFA_FCS_OS_STR_LEN);
704a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
705a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
706a36c61f9SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
707a36c61f9SKrishna Gudipati 	} else {
708a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
709a36c61f9SKrishna Gudipati 			(char *)driver_info->host_os_name,
710a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
711a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
712a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
713a36c61f9SKrishna Gudipati 			sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
714a36c61f9SKrishna Gudipati 
715a36c61f9SKrishna Gudipati 		/* Append host OS Patch Info */
716a36c61f9SKrishna Gudipati 		strncat((char *)&port_cfg->sym_name,
717a36c61f9SKrishna Gudipati 			(char *)driver_info->host_os_patch,
718a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
719a36c61f9SKrishna Gudipati 	}
720a36c61f9SKrishna Gudipati 
721a36c61f9SKrishna Gudipati 	/* null terminate */
722a36c61f9SKrishna Gudipati 	port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
723a36c61f9SKrishna Gudipati }
724a36c61f9SKrishna Gudipati 
7255fbe25c7SJing Huang /*
726a36c61f9SKrishna Gudipati  * bfa lps login completion callback
727a36c61f9SKrishna Gudipati  */
728a36c61f9SKrishna Gudipati void
729a36c61f9SKrishna Gudipati bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
730a36c61f9SKrishna Gudipati {
731a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = uarg;
732a36c61f9SKrishna Gudipati 
733a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
734a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, status);
735a36c61f9SKrishna Gudipati 
736a36c61f9SKrishna Gudipati 	switch (status) {
737a36c61f9SKrishna Gudipati 	case BFA_STATUS_OK:
738a36c61f9SKrishna Gudipati 		fabric->stats.flogi_accepts++;
739a36c61f9SKrishna Gudipati 		break;
740a36c61f9SKrishna Gudipati 
741a36c61f9SKrishna Gudipati 	case BFA_STATUS_INVALID_MAC:
742a36c61f9SKrishna Gudipati 		/* Only for CNA */
743a36c61f9SKrishna Gudipati 		fabric->stats.flogi_acc_err++;
744a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
745a36c61f9SKrishna Gudipati 
746a36c61f9SKrishna Gudipati 		return;
747a36c61f9SKrishna Gudipati 
748a36c61f9SKrishna Gudipati 	case BFA_STATUS_EPROTOCOL:
749f7f73812SMaggie Zhang 		switch (fabric->lps->ext_status) {
750a36c61f9SKrishna Gudipati 		case BFA_EPROTO_BAD_ACCEPT:
751a36c61f9SKrishna Gudipati 			fabric->stats.flogi_acc_err++;
752a36c61f9SKrishna Gudipati 			break;
753a36c61f9SKrishna Gudipati 
754a36c61f9SKrishna Gudipati 		case BFA_EPROTO_UNKNOWN_RSP:
755a36c61f9SKrishna Gudipati 			fabric->stats.flogi_unknown_rsp++;
756a36c61f9SKrishna Gudipati 			break;
757a36c61f9SKrishna Gudipati 
758a36c61f9SKrishna Gudipati 		default:
759a36c61f9SKrishna Gudipati 			break;
760a36c61f9SKrishna Gudipati 		}
761a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
762a36c61f9SKrishna Gudipati 
763a36c61f9SKrishna Gudipati 		return;
764a36c61f9SKrishna Gudipati 
765a36c61f9SKrishna Gudipati 	case BFA_STATUS_FABRIC_RJT:
766a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rejects++;
767a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
768a36c61f9SKrishna Gudipati 		return;
769a36c61f9SKrishna Gudipati 
770a36c61f9SKrishna Gudipati 	default:
771a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rsp_err++;
772a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
773a36c61f9SKrishna Gudipati 		return;
774a36c61f9SKrishna Gudipati 	}
775a36c61f9SKrishna Gudipati 
776f7f73812SMaggie Zhang 	fabric->bb_credit = fabric->lps->pr_bbcred;
777a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bb_credit);
778a36c61f9SKrishna Gudipati 
779f7f73812SMaggie Zhang 	if (!(fabric->lps->brcd_switch))
780f7f73812SMaggie Zhang 		fabric->fabric_name =  fabric->lps->pr_nwwn;
781a36c61f9SKrishna Gudipati 
782a36c61f9SKrishna Gudipati 	/*
783a36c61f9SKrishna Gudipati 	 * Check port type. It should be 1 = F-port.
784a36c61f9SKrishna Gudipati 	 */
785f7f73812SMaggie Zhang 	if (fabric->lps->fport) {
786f7f73812SMaggie Zhang 		fabric->bport.pid = fabric->lps->lp_pid;
787f7f73812SMaggie Zhang 		fabric->is_npiv = fabric->lps->npiv_en;
788f7f73812SMaggie Zhang 		fabric->is_auth = fabric->lps->auth_req;
789a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
790a36c61f9SKrishna Gudipati 	} else {
791a36c61f9SKrishna Gudipati 		/*
792a36c61f9SKrishna Gudipati 		 * Nport-2-Nport direct attached
793a36c61f9SKrishna Gudipati 		 */
794a36c61f9SKrishna Gudipati 		fabric->bport.port_topo.pn2n.rem_port_wwn =
795f7f73812SMaggie Zhang 			fabric->lps->pr_pwwn;
796a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
797a36c61f9SKrishna Gudipati 	}
798a36c61f9SKrishna Gudipati 
799a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.pid);
800a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->is_npiv);
801a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->is_auth);
802a36c61f9SKrishna Gudipati }
8035fbe25c7SJing Huang /*
804a36c61f9SKrishna Gudipati  *		Allocate and send FLOGI.
805a36c61f9SKrishna Gudipati  */
806a36c61f9SKrishna Gudipati static void
807a36c61f9SKrishna Gudipati bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
808a36c61f9SKrishna Gudipati {
809a36c61f9SKrishna Gudipati 	struct bfa_s		*bfa = fabric->fcs->bfa;
810a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s	*pcfg = &fabric->bport.port_cfg;
811a36c61f9SKrishna Gudipati 	u8			alpa = 0;
812a36c61f9SKrishna Gudipati 
813a36c61f9SKrishna Gudipati 	if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
814a36c61f9SKrishna Gudipati 		alpa = bfa_fcport_get_myalpa(bfa);
815a36c61f9SKrishna Gudipati 
816a36c61f9SKrishna Gudipati 	bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
817a36c61f9SKrishna Gudipati 		      pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
818a36c61f9SKrishna Gudipati 
819a36c61f9SKrishna Gudipati 	fabric->stats.flogi_sent++;
820a36c61f9SKrishna Gudipati }
821a36c61f9SKrishna Gudipati 
822a36c61f9SKrishna Gudipati static void
823a36c61f9SKrishna Gudipati bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
824a36c61f9SKrishna Gudipati {
825a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
826a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
827a36c61f9SKrishna Gudipati 
828a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->fabric_name);
829a36c61f9SKrishna Gudipati 
830a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_set_opertype(fabric);
831a36c61f9SKrishna Gudipati 	fabric->stats.fabric_onlines++;
832a36c61f9SKrishna Gudipati 
8335fbe25c7SJing Huang 	/*
834a36c61f9SKrishna Gudipati 	 * notify online event to base and then virtual ports
835a36c61f9SKrishna Gudipati 	 */
836a36c61f9SKrishna Gudipati 	bfa_fcs_lport_online(&fabric->bport);
837a36c61f9SKrishna Gudipati 
838a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
839a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
840a36c61f9SKrishna Gudipati 		bfa_fcs_vport_online(vport);
841a36c61f9SKrishna Gudipati 	}
842a36c61f9SKrishna Gudipati }
843a36c61f9SKrishna Gudipati 
844a36c61f9SKrishna Gudipati static void
845a36c61f9SKrishna Gudipati bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
846a36c61f9SKrishna Gudipati {
847a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
848a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
849a36c61f9SKrishna Gudipati 
850a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->fabric_name);
851a36c61f9SKrishna Gudipati 	fabric->stats.fabric_offlines++;
852a36c61f9SKrishna Gudipati 
8535fbe25c7SJing Huang 	/*
854a36c61f9SKrishna Gudipati 	 * notify offline event first to vports and then base port.
855a36c61f9SKrishna Gudipati 	 */
856a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
857a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
858a36c61f9SKrishna Gudipati 		bfa_fcs_vport_offline(vport);
859a36c61f9SKrishna Gudipati 	}
860a36c61f9SKrishna Gudipati 
861a36c61f9SKrishna Gudipati 	bfa_fcs_lport_offline(&fabric->bport);
862a36c61f9SKrishna Gudipati 
863a36c61f9SKrishna Gudipati 	fabric->fabric_name = 0;
864a36c61f9SKrishna Gudipati 	fabric->fabric_ip_addr[0] = 0;
865a36c61f9SKrishna Gudipati }
866a36c61f9SKrishna Gudipati 
867a36c61f9SKrishna Gudipati static void
868a36c61f9SKrishna Gudipati bfa_fcs_fabric_delay(void *cbarg)
869a36c61f9SKrishna Gudipati {
870a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
871a36c61f9SKrishna Gudipati 
872a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
873a36c61f9SKrishna Gudipati }
874a36c61f9SKrishna Gudipati 
8755fbe25c7SJing Huang /*
876a36c61f9SKrishna Gudipati  * Delete all vports and wait for vport delete completions.
877a36c61f9SKrishna Gudipati  */
878a36c61f9SKrishna Gudipati static void
879a36c61f9SKrishna Gudipati bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
880a36c61f9SKrishna Gudipati {
881a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
882a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
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_fcs_delete(vport);
887a36c61f9SKrishna Gudipati 	}
888a36c61f9SKrishna Gudipati 
889a36c61f9SKrishna Gudipati 	bfa_fcs_lport_delete(&fabric->bport);
890a36c61f9SKrishna Gudipati 	bfa_wc_wait(&fabric->wc);
891a36c61f9SKrishna Gudipati }
892a36c61f9SKrishna Gudipati 
893a36c61f9SKrishna Gudipati static void
894a36c61f9SKrishna Gudipati bfa_fcs_fabric_delete_comp(void *cbarg)
895a36c61f9SKrishna Gudipati {
896a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
897a36c61f9SKrishna Gudipati 
898a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
899a36c61f9SKrishna Gudipati }
900a36c61f9SKrishna Gudipati 
9015fbe25c7SJing Huang /*
902a36c61f9SKrishna Gudipati  *  fcs_fabric_public fabric public functions
903a36c61f9SKrishna Gudipati  */
904a36c61f9SKrishna Gudipati 
9055fbe25c7SJing Huang /*
906a36c61f9SKrishna Gudipati  * Attach time initialization.
907a36c61f9SKrishna Gudipati  */
908a36c61f9SKrishna Gudipati void
909a36c61f9SKrishna Gudipati bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
910a36c61f9SKrishna Gudipati {
911a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
912a36c61f9SKrishna Gudipati 
913a36c61f9SKrishna Gudipati 	fabric = &fcs->fabric;
9146a18b167SJing Huang 	memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
915a36c61f9SKrishna Gudipati 
9165fbe25c7SJing Huang 	/*
917a36c61f9SKrishna Gudipati 	 * Initialize base fabric.
918a36c61f9SKrishna Gudipati 	 */
919a36c61f9SKrishna Gudipati 	fabric->fcs = fcs;
920a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&fabric->vport_q);
921a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&fabric->vf_q);
922a36c61f9SKrishna Gudipati 	fabric->lps = bfa_lps_alloc(fcs->bfa);
923d4b671c5SJing Huang 	WARN_ON(!fabric->lps);
924a36c61f9SKrishna Gudipati 
9255fbe25c7SJing Huang 	/*
926a36c61f9SKrishna Gudipati 	 * Initialize fabric delete completion handler. Fabric deletion is
927a36c61f9SKrishna Gudipati 	 * complete when the last vport delete is complete.
928a36c61f9SKrishna Gudipati 	 */
929a36c61f9SKrishna Gudipati 	bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric);
930a36c61f9SKrishna Gudipati 	bfa_wc_up(&fabric->wc); /* For the base port */
931a36c61f9SKrishna Gudipati 
932a36c61f9SKrishna Gudipati 	bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
933a36c61f9SKrishna Gudipati 	bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
934a36c61f9SKrishna Gudipati }
935a36c61f9SKrishna Gudipati 
936a36c61f9SKrishna Gudipati void
937a36c61f9SKrishna Gudipati bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
938a36c61f9SKrishna Gudipati {
939a36c61f9SKrishna Gudipati 	bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
940a36c61f9SKrishna Gudipati 	bfa_trc(fcs, 0);
941a36c61f9SKrishna Gudipati }
942a36c61f9SKrishna Gudipati 
9435fbe25c7SJing Huang /*
944a36c61f9SKrishna Gudipati  *   Module cleanup
945a36c61f9SKrishna Gudipati  */
946a36c61f9SKrishna Gudipati void
947a36c61f9SKrishna Gudipati bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
948a36c61f9SKrishna Gudipati {
949a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
950a36c61f9SKrishna Gudipati 
951a36c61f9SKrishna Gudipati 	bfa_trc(fcs, 0);
952a36c61f9SKrishna Gudipati 
9535fbe25c7SJing Huang 	/*
954a36c61f9SKrishna Gudipati 	 * Cleanup base fabric.
955a36c61f9SKrishna Gudipati 	 */
956a36c61f9SKrishna Gudipati 	fabric = &fcs->fabric;
957a36c61f9SKrishna Gudipati 	bfa_lps_delete(fabric->lps);
958a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE);
959a36c61f9SKrishna Gudipati }
960a36c61f9SKrishna Gudipati 
9615fbe25c7SJing Huang /*
962a36c61f9SKrishna Gudipati  * Fabric module start -- kick starts FCS actions
963a36c61f9SKrishna Gudipati  */
964a36c61f9SKrishna Gudipati void
965a36c61f9SKrishna Gudipati bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
966a36c61f9SKrishna Gudipati {
967a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
968a36c61f9SKrishna Gudipati 
969a36c61f9SKrishna Gudipati 	bfa_trc(fcs, 0);
970a36c61f9SKrishna Gudipati 	fabric = &fcs->fabric;
971a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
972a36c61f9SKrishna Gudipati }
973a36c61f9SKrishna Gudipati 
974a36c61f9SKrishna Gudipati 
9755fbe25c7SJing Huang /*
976a36c61f9SKrishna Gudipati  *   Link up notification from BFA physical port module.
977a36c61f9SKrishna Gudipati  */
978a36c61f9SKrishna Gudipati void
979a36c61f9SKrishna Gudipati bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
980a36c61f9SKrishna Gudipati {
981a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
982a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
983a36c61f9SKrishna Gudipati }
984a36c61f9SKrishna Gudipati 
9855fbe25c7SJing Huang /*
986a36c61f9SKrishna Gudipati  *   Link down notification from BFA physical port module.
987a36c61f9SKrishna Gudipati  */
988a36c61f9SKrishna Gudipati void
989a36c61f9SKrishna Gudipati bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
990a36c61f9SKrishna Gudipati {
991a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
992a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
993a36c61f9SKrishna Gudipati }
994a36c61f9SKrishna Gudipati 
9955fbe25c7SJing Huang /*
996a36c61f9SKrishna Gudipati  *   A child vport is being created in the fabric.
997a36c61f9SKrishna Gudipati  *
998a36c61f9SKrishna Gudipati  *   Call from vport module at vport creation. A list of base port and vports
999a36c61f9SKrishna Gudipati  *   belonging to a fabric is maintained to propagate link events.
1000a36c61f9SKrishna Gudipati  *
1001a36c61f9SKrishna Gudipati  *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
1002a36c61f9SKrishna Gudipati  *   param[in] vport  - Vport being created.
1003a36c61f9SKrishna Gudipati  *
1004a36c61f9SKrishna Gudipati  *   @return None (always succeeds)
1005a36c61f9SKrishna Gudipati  */
1006a36c61f9SKrishna Gudipati void
1007a36c61f9SKrishna Gudipati bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
1008a36c61f9SKrishna Gudipati 			struct bfa_fcs_vport_s *vport)
1009a36c61f9SKrishna Gudipati {
10105fbe25c7SJing Huang 	/*
1011a36c61f9SKrishna Gudipati 	 * - add vport to fabric's vport_q
1012a36c61f9SKrishna Gudipati 	 */
1013a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->vf_id);
1014a36c61f9SKrishna Gudipati 
1015a36c61f9SKrishna Gudipati 	list_add_tail(&vport->qe, &fabric->vport_q);
1016a36c61f9SKrishna Gudipati 	fabric->num_vports++;
1017a36c61f9SKrishna Gudipati 	bfa_wc_up(&fabric->wc);
1018a36c61f9SKrishna Gudipati }
1019a36c61f9SKrishna Gudipati 
10205fbe25c7SJing Huang /*
1021a36c61f9SKrishna Gudipati  *   A child vport is being deleted from fabric.
1022a36c61f9SKrishna Gudipati  *
1023a36c61f9SKrishna Gudipati  *   Vport is being deleted.
1024a36c61f9SKrishna Gudipati  */
1025a36c61f9SKrishna Gudipati void
1026a36c61f9SKrishna Gudipati bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
1027a36c61f9SKrishna Gudipati 			struct bfa_fcs_vport_s *vport)
1028a36c61f9SKrishna Gudipati {
1029a36c61f9SKrishna Gudipati 	list_del(&vport->qe);
1030a36c61f9SKrishna Gudipati 	fabric->num_vports--;
1031a36c61f9SKrishna Gudipati 	bfa_wc_down(&fabric->wc);
1032a36c61f9SKrishna Gudipati }
1033a36c61f9SKrishna Gudipati 
1034a36c61f9SKrishna Gudipati 
10355fbe25c7SJing Huang /*
103625985edcSLucas De Marchi  * Lookup for a vport within a fabric given its pwwn
1037a36c61f9SKrishna Gudipati  */
1038a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *
1039a36c61f9SKrishna Gudipati bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
1040a36c61f9SKrishna Gudipati {
1041a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1042a36c61f9SKrishna Gudipati 	struct list_head	      *qe;
1043a36c61f9SKrishna Gudipati 
1044a36c61f9SKrishna Gudipati 	list_for_each(qe, &fabric->vport_q) {
1045a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1046a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_get_pwwn(&vport->lport) == pwwn)
1047a36c61f9SKrishna Gudipati 			return vport;
1048a36c61f9SKrishna Gudipati 	}
1049a36c61f9SKrishna Gudipati 
1050a36c61f9SKrishna Gudipati 	return NULL;
1051a36c61f9SKrishna Gudipati }
1052a36c61f9SKrishna Gudipati 
1053a36c61f9SKrishna Gudipati 
1054a36c61f9SKrishna Gudipati /*
1055a36c61f9SKrishna Gudipati  *  Get OUI of the attached switch.
1056a36c61f9SKrishna Gudipati  *
1057a36c61f9SKrishna Gudipati  *  Note : Use of this function should be avoided as much as possible.
1058a36c61f9SKrishna Gudipati  *         This function should be used only if there is any requirement
1059a36c61f9SKrishna Gudipati *          to check for FOS version below 6.3.
1060a36c61f9SKrishna Gudipati  *         To check if the attached fabric is a brocade fabric, use
1061a36c61f9SKrishna Gudipati  *         bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
1062a36c61f9SKrishna Gudipati  *         or above only.
1063a36c61f9SKrishna Gudipati  */
1064a36c61f9SKrishna Gudipati 
1065a36c61f9SKrishna Gudipati u16
1066a36c61f9SKrishna Gudipati bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
1067a36c61f9SKrishna Gudipati {
1068a36c61f9SKrishna Gudipati 	wwn_t fab_nwwn;
1069a36c61f9SKrishna Gudipati 	u8 *tmp;
1070a36c61f9SKrishna Gudipati 	u16 oui;
1071a36c61f9SKrishna Gudipati 
1072f7f73812SMaggie Zhang 	fab_nwwn = fabric->lps->pr_nwwn;
1073a36c61f9SKrishna Gudipati 
1074a36c61f9SKrishna Gudipati 	tmp = (u8 *)&fab_nwwn;
1075a36c61f9SKrishna Gudipati 	oui = (tmp[3] << 8) | tmp[4];
1076a36c61f9SKrishna Gudipati 
1077a36c61f9SKrishna Gudipati 	return oui;
1078a36c61f9SKrishna Gudipati }
10795fbe25c7SJing Huang /*
1080a36c61f9SKrishna Gudipati  *		Unsolicited frame receive handling.
1081a36c61f9SKrishna Gudipati  */
1082a36c61f9SKrishna Gudipati void
1083a36c61f9SKrishna Gudipati bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1084a36c61f9SKrishna Gudipati 		       u16 len)
1085a36c61f9SKrishna Gudipati {
1086a36c61f9SKrishna Gudipati 	u32	pid = fchs->d_id;
1087a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1088a36c61f9SKrishna Gudipati 	struct list_head	      *qe;
1089a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1090a36c61f9SKrishna Gudipati 	struct fc_logi_s *flogi = (struct fc_logi_s *) els_cmd;
1091a36c61f9SKrishna Gudipati 
1092a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, len);
1093a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, pid);
1094a36c61f9SKrishna Gudipati 
10955fbe25c7SJing Huang 	/*
1096a36c61f9SKrishna Gudipati 	 * Look for our own FLOGI frames being looped back. This means an
1097a36c61f9SKrishna Gudipati 	 * external loopback cable is in place. Our own FLOGI frames are
1098a36c61f9SKrishna Gudipati 	 * sometimes looped back when switch port gets temporarily bypassed.
1099a36c61f9SKrishna Gudipati 	 */
1100f16a1750SMaggie Zhang 	if ((pid == bfa_ntoh3b(FC_FABRIC_PORT)) &&
1101a36c61f9SKrishna Gudipati 	    (els_cmd->els_code == FC_ELS_FLOGI) &&
1102a36c61f9SKrishna Gudipati 	    (flogi->port_name == bfa_fcs_lport_get_pwwn(&fabric->bport))) {
1103a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
1104a36c61f9SKrishna Gudipati 		return;
1105a36c61f9SKrishna Gudipati 	}
1106a36c61f9SKrishna Gudipati 
11075fbe25c7SJing Huang 	/*
1108a36c61f9SKrishna Gudipati 	 * FLOGI/EVFP exchanges should be consumed by base fabric.
1109a36c61f9SKrishna Gudipati 	 */
1110f16a1750SMaggie Zhang 	if (fchs->d_id == bfa_hton3b(FC_FABRIC_PORT)) {
1111a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, pid);
1112a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_process_uf(fabric, fchs, len);
1113a36c61f9SKrishna Gudipati 		return;
1114a36c61f9SKrishna Gudipati 	}
1115a36c61f9SKrishna Gudipati 
1116a36c61f9SKrishna Gudipati 	if (fabric->bport.pid == pid) {
11175fbe25c7SJing Huang 		/*
1118a36c61f9SKrishna Gudipati 		 * All authentication frames should be routed to auth
1119a36c61f9SKrishna Gudipati 		 */
1120a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, els_cmd->els_code);
1121a36c61f9SKrishna Gudipati 		if (els_cmd->els_code == FC_ELS_AUTH) {
1122a36c61f9SKrishna Gudipati 			bfa_trc(fabric->fcs, els_cmd->els_code);
1123a36c61f9SKrishna Gudipati 			return;
1124a36c61f9SKrishna Gudipati 		}
1125a36c61f9SKrishna Gudipati 
1126a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
1127a36c61f9SKrishna Gudipati 		bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
1128a36c61f9SKrishna Gudipati 		return;
1129a36c61f9SKrishna Gudipati 	}
1130a36c61f9SKrishna Gudipati 
11315fbe25c7SJing Huang 	/*
1132a36c61f9SKrishna Gudipati 	 * look for a matching local port ID
1133a36c61f9SKrishna Gudipati 	 */
1134a36c61f9SKrishna Gudipati 	list_for_each(qe, &fabric->vport_q) {
1135a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1136a36c61f9SKrishna Gudipati 		if (vport->lport.pid == pid) {
1137a36c61f9SKrishna Gudipati 			bfa_fcs_lport_uf_recv(&vport->lport, fchs, len);
1138a36c61f9SKrishna Gudipati 			return;
1139a36c61f9SKrishna Gudipati 		}
1140a36c61f9SKrishna Gudipati 	}
1141a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, els_cmd->els_code);
1142a36c61f9SKrishna Gudipati 	bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
1143a36c61f9SKrishna Gudipati }
1144a36c61f9SKrishna Gudipati 
11455fbe25c7SJing Huang /*
1146a36c61f9SKrishna Gudipati  *		Unsolicited frames to be processed by fabric.
1147a36c61f9SKrishna Gudipati  */
1148a36c61f9SKrishna Gudipati static void
1149a36c61f9SKrishna Gudipati bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1150a36c61f9SKrishna Gudipati 			  u16 len)
1151a36c61f9SKrishna Gudipati {
1152a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1153a36c61f9SKrishna Gudipati 
1154a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, els_cmd->els_code);
1155a36c61f9SKrishna Gudipati 
1156a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
1157a36c61f9SKrishna Gudipati 	case FC_ELS_FLOGI:
1158a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_process_flogi(fabric, fchs, len);
1159a36c61f9SKrishna Gudipati 		break;
1160a36c61f9SKrishna Gudipati 
1161a36c61f9SKrishna Gudipati 	default:
1162a36c61f9SKrishna Gudipati 		/*
1163a36c61f9SKrishna Gudipati 		 * need to generate a LS_RJT
1164a36c61f9SKrishna Gudipati 		 */
1165a36c61f9SKrishna Gudipati 		break;
1166a36c61f9SKrishna Gudipati 	}
1167a36c61f9SKrishna Gudipati }
1168a36c61f9SKrishna Gudipati 
11695fbe25c7SJing Huang /*
1170a36c61f9SKrishna Gudipati  *	Process	incoming FLOGI
1171a36c61f9SKrishna Gudipati  */
1172a36c61f9SKrishna Gudipati static void
1173a36c61f9SKrishna Gudipati bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
1174a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
1175a36c61f9SKrishna Gudipati {
1176a36c61f9SKrishna Gudipati 	struct fc_logi_s *flogi = (struct fc_logi_s *) (fchs + 1);
1177a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *bport = &fabric->bport;
1178a36c61f9SKrishna Gudipati 
1179a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fchs->s_id);
1180a36c61f9SKrishna Gudipati 
1181a36c61f9SKrishna Gudipati 	fabric->stats.flogi_rcvd++;
1182a36c61f9SKrishna Gudipati 	/*
1183a36c61f9SKrishna Gudipati 	 * Check port type. It should be 0 = n-port.
1184a36c61f9SKrishna Gudipati 	 */
1185a36c61f9SKrishna Gudipati 	if (flogi->csp.port_type) {
1186a36c61f9SKrishna Gudipati 		/*
1187a36c61f9SKrishna Gudipati 		 * @todo: may need to send a LS_RJT
1188a36c61f9SKrishna Gudipati 		 */
1189a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, flogi->port_name);
1190a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rejected++;
1191a36c61f9SKrishna Gudipati 		return;
1192a36c61f9SKrishna Gudipati 	}
1193a36c61f9SKrishna Gudipati 
1194ba816ea8SJing Huang 	fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred);
1195a36c61f9SKrishna Gudipati 	bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
1196a36c61f9SKrishna Gudipati 	bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
1197a36c61f9SKrishna Gudipati 
1198a36c61f9SKrishna Gudipati 	/*
1199a36c61f9SKrishna Gudipati 	 * Send a Flogi Acc
1200a36c61f9SKrishna Gudipati 	 */
1201a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_send_flogi_acc(fabric);
1202a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
1203a36c61f9SKrishna Gudipati }
1204a36c61f9SKrishna Gudipati 
1205a36c61f9SKrishna Gudipati static void
1206a36c61f9SKrishna Gudipati bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1207a36c61f9SKrishna Gudipati {
1208a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
1209a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
1210a36c61f9SKrishna Gudipati 	struct bfa_s	  *bfa = fabric->fcs->bfa;
1211a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1212a36c61f9SKrishna Gudipati 	u16	reqlen;
1213a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1214a36c61f9SKrishna Gudipati 
1215a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
12165fbe25c7SJing Huang 	/*
1217a36c61f9SKrishna Gudipati 	 * Do not expect this failure -- expect remote node to retry
1218a36c61f9SKrishna Gudipati 	 */
1219a36c61f9SKrishna Gudipati 	if (!fcxp)
1220a36c61f9SKrishna Gudipati 		return;
1221a36c61f9SKrishna Gudipati 
1222a36c61f9SKrishna Gudipati 	reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1223f16a1750SMaggie Zhang 				    bfa_hton3b(FC_FABRIC_PORT),
1224a36c61f9SKrishna Gudipati 				    n2n_port->reply_oxid, pcfg->pwwn,
1225a36c61f9SKrishna Gudipati 				    pcfg->nwwn,
1226a36c61f9SKrishna Gudipati 				    bfa_fcport_get_maxfrsize(bfa),
1227a36c61f9SKrishna Gudipati 				    bfa_fcport_get_rx_bbcredit(bfa));
1228a36c61f9SKrishna Gudipati 
1229f7f73812SMaggie Zhang 	bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->lp_tag,
1230a36c61f9SKrishna Gudipati 		      BFA_FALSE, FC_CLASS_3,
1231a36c61f9SKrishna Gudipati 		      reqlen, &fchs, bfa_fcs_fabric_flogiacc_comp, fabric,
1232a36c61f9SKrishna Gudipati 		      FC_MAX_PDUSZ, 0);
1233a36c61f9SKrishna Gudipati }
1234a36c61f9SKrishna Gudipati 
12355fbe25c7SJing Huang /*
1236a36c61f9SKrishna Gudipati  *   Flogi Acc completion callback.
1237a36c61f9SKrishna Gudipati  */
1238a36c61f9SKrishna Gudipati static void
1239a36c61f9SKrishna Gudipati bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1240a36c61f9SKrishna Gudipati 			     bfa_status_t status, u32 rsp_len,
1241a36c61f9SKrishna Gudipati 			     u32 resid_len, struct fchs_s *rspfchs)
1242a36c61f9SKrishna Gudipati {
1243a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
1244a36c61f9SKrishna Gudipati 
1245a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, status);
1246a36c61f9SKrishna Gudipati }
1247a36c61f9SKrishna Gudipati 
1248a36c61f9SKrishna Gudipati /*
1249a36c61f9SKrishna Gudipati  *
1250a36c61f9SKrishna Gudipati  * @param[in] fabric - fabric
1251a36c61f9SKrishna Gudipati  * @param[in] wwn_t - new fabric name
1252a36c61f9SKrishna Gudipati  *
1253a36c61f9SKrishna Gudipati  * @return - none
1254a36c61f9SKrishna Gudipati  */
1255a36c61f9SKrishna Gudipati void
1256a36c61f9SKrishna Gudipati bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1257a36c61f9SKrishna Gudipati 			       wwn_t fabric_name)
1258a36c61f9SKrishna Gudipati {
1259a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
1260a36c61f9SKrishna Gudipati 	char	pwwn_ptr[BFA_STRING_32];
1261a36c61f9SKrishna Gudipati 	char	fwwn_ptr[BFA_STRING_32];
1262a36c61f9SKrishna Gudipati 
1263a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric_name);
1264a36c61f9SKrishna Gudipati 
1265a36c61f9SKrishna Gudipati 	if (fabric->fabric_name == 0) {
1266a36c61f9SKrishna Gudipati 		/*
1267a36c61f9SKrishna Gudipati 		 * With BRCD switches, we don't get Fabric Name in FLOGI.
1268a36c61f9SKrishna Gudipati 		 * Don't generate a fabric name change event in this case.
1269a36c61f9SKrishna Gudipati 		 */
1270a36c61f9SKrishna Gudipati 		fabric->fabric_name = fabric_name;
1271a36c61f9SKrishna Gudipati 	} else {
1272a36c61f9SKrishna Gudipati 		fabric->fabric_name = fabric_name;
1273a36c61f9SKrishna Gudipati 		wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport));
1274a36c61f9SKrishna Gudipati 		wwn2str(fwwn_ptr,
1275a36c61f9SKrishna Gudipati 			bfa_fcs_lport_get_fabric_name(&fabric->bport));
127688166242SJing Huang 		BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
1277a36c61f9SKrishna Gudipati 			"Base port WWN = %s Fabric WWN = %s\n",
1278a36c61f9SKrishna Gudipati 			pwwn_ptr, fwwn_ptr);
1279a36c61f9SKrishna Gudipati 	}
1280a36c61f9SKrishna Gudipati }
1281a36c61f9SKrishna Gudipati 
12825fbe25c7SJing Huang /*
1283a36c61f9SKrishna Gudipati  *	Returns FCS vf structure for a given vf_id.
1284a36c61f9SKrishna Gudipati  *
1285a36c61f9SKrishna Gudipati  *	param[in]	vf_id - VF_ID
1286a36c61f9SKrishna Gudipati  *
1287a36c61f9SKrishna Gudipati  *	return
1288a36c61f9SKrishna Gudipati  *	If lookup succeeds, retuns fcs vf object, otherwise returns NULL
1289a36c61f9SKrishna Gudipati  */
1290a36c61f9SKrishna Gudipati bfa_fcs_vf_t   *
1291a36c61f9SKrishna Gudipati bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id)
1292a36c61f9SKrishna Gudipati {
1293a36c61f9SKrishna Gudipati 	bfa_trc(fcs, vf_id);
1294a36c61f9SKrishna Gudipati 	if (vf_id == FC_VF_ID_NULL)
1295a36c61f9SKrishna Gudipati 		return &fcs->fabric;
1296a36c61f9SKrishna Gudipati 
1297a36c61f9SKrishna Gudipati 	return NULL;
1298a36c61f9SKrishna Gudipati }
1299a36c61f9SKrishna Gudipati 
13005fbe25c7SJing Huang /*
1301a36c61f9SKrishna Gudipati  * BFA FCS PPORT ( physical port)
1302a36c61f9SKrishna Gudipati  */
1303a36c61f9SKrishna Gudipati static void
1304a36c61f9SKrishna Gudipati bfa_fcs_port_event_handler(void *cbarg, enum bfa_port_linkstate event)
1305a36c61f9SKrishna Gudipati {
1306a36c61f9SKrishna Gudipati 	struct bfa_fcs_s      *fcs = cbarg;
1307a36c61f9SKrishna Gudipati 
1308a36c61f9SKrishna Gudipati 	bfa_trc(fcs, event);
1309a36c61f9SKrishna Gudipati 
1310a36c61f9SKrishna Gudipati 	switch (event) {
1311a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKUP:
1312a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_link_up(&fcs->fabric);
1313a36c61f9SKrishna Gudipati 		break;
1314a36c61f9SKrishna Gudipati 
1315a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKDOWN:
1316a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_link_down(&fcs->fabric);
1317a36c61f9SKrishna Gudipati 		break;
1318a36c61f9SKrishna Gudipati 
1319a36c61f9SKrishna Gudipati 	default:
1320d4b671c5SJing Huang 		WARN_ON(1);
1321a36c61f9SKrishna Gudipati 	}
1322a36c61f9SKrishna Gudipati }
1323a36c61f9SKrishna Gudipati 
1324a36c61f9SKrishna Gudipati void
1325a36c61f9SKrishna Gudipati bfa_fcs_port_attach(struct bfa_fcs_s *fcs)
1326a36c61f9SKrishna Gudipati {
1327a36c61f9SKrishna Gudipati 	bfa_fcport_event_register(fcs->bfa, bfa_fcs_port_event_handler, fcs);
1328a36c61f9SKrishna Gudipati }
1329a36c61f9SKrishna Gudipati 
13305fbe25c7SJing Huang /*
1331a36c61f9SKrishna Gudipati  * BFA FCS UF ( Unsolicited Frames)
1332a36c61f9SKrishna Gudipati  */
1333a36c61f9SKrishna Gudipati 
13345fbe25c7SJing Huang /*
1335a36c61f9SKrishna Gudipati  *		BFA callback for unsolicited frame receive handler.
1336a36c61f9SKrishna Gudipati  *
1337a36c61f9SKrishna Gudipati  * @param[in]		cbarg		callback arg for receive handler
1338a36c61f9SKrishna Gudipati  * @param[in]		uf		unsolicited frame descriptor
1339a36c61f9SKrishna Gudipati  *
1340a36c61f9SKrishna Gudipati  * @return None
1341a36c61f9SKrishna Gudipati  */
1342a36c61f9SKrishna Gudipati static void
1343a36c61f9SKrishna Gudipati bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
1344a36c61f9SKrishna Gudipati {
1345a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs = (struct bfa_fcs_s *) cbarg;
1346a36c61f9SKrishna Gudipati 	struct fchs_s	*fchs = bfa_uf_get_frmbuf(uf);
1347a36c61f9SKrishna Gudipati 	u16	len = bfa_uf_get_frmlen(uf);
1348a36c61f9SKrishna Gudipati 	struct fc_vft_s *vft;
1349a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1350a36c61f9SKrishna Gudipati 
13515fbe25c7SJing Huang 	/*
1352a36c61f9SKrishna Gudipati 	 * check for VFT header
1353a36c61f9SKrishna Gudipati 	 */
1354a36c61f9SKrishna Gudipati 	if (fchs->routing == FC_RTG_EXT_HDR &&
1355a36c61f9SKrishna Gudipati 	    fchs->cat_info == FC_CAT_VFT_HDR) {
1356a36c61f9SKrishna Gudipati 		bfa_stats(fcs, uf.tagged);
1357a36c61f9SKrishna Gudipati 		vft = bfa_uf_get_frmbuf(uf);
1358a36c61f9SKrishna Gudipati 		if (fcs->port_vfid == vft->vf_id)
1359a36c61f9SKrishna Gudipati 			fabric = &fcs->fabric;
1360a36c61f9SKrishna Gudipati 		else
1361a36c61f9SKrishna Gudipati 			fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id);
1362a36c61f9SKrishna Gudipati 
13635fbe25c7SJing Huang 		/*
1364a36c61f9SKrishna Gudipati 		 * drop frame if vfid is unknown
1365a36c61f9SKrishna Gudipati 		 */
1366a36c61f9SKrishna Gudipati 		if (!fabric) {
1367d4b671c5SJing Huang 			WARN_ON(1);
1368a36c61f9SKrishna Gudipati 			bfa_stats(fcs, uf.vfid_unknown);
1369a36c61f9SKrishna Gudipati 			bfa_uf_free(uf);
1370a36c61f9SKrishna Gudipati 			return;
1371a36c61f9SKrishna Gudipati 		}
1372a36c61f9SKrishna Gudipati 
13735fbe25c7SJing Huang 		/*
1374a36c61f9SKrishna Gudipati 		 * skip vft header
1375a36c61f9SKrishna Gudipati 		 */
1376a36c61f9SKrishna Gudipati 		fchs = (struct fchs_s *) (vft + 1);
1377a36c61f9SKrishna Gudipati 		len -= sizeof(struct fc_vft_s);
1378a36c61f9SKrishna Gudipati 
1379a36c61f9SKrishna Gudipati 		bfa_trc(fcs, vft->vf_id);
1380a36c61f9SKrishna Gudipati 	} else {
1381a36c61f9SKrishna Gudipati 		bfa_stats(fcs, uf.untagged);
1382a36c61f9SKrishna Gudipati 		fabric = &fcs->fabric;
1383a36c61f9SKrishna Gudipati 	}
1384a36c61f9SKrishna Gudipati 
1385a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[0]);
1386a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[1]);
1387a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[2]);
1388a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[3]);
1389a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[4]);
1390a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[5]);
1391a36c61f9SKrishna Gudipati 	bfa_trc(fcs, len);
1392a36c61f9SKrishna Gudipati 
1393a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_uf_recv(fabric, fchs, len);
1394a36c61f9SKrishna Gudipati 	bfa_uf_free(uf);
1395a36c61f9SKrishna Gudipati }
1396a36c61f9SKrishna Gudipati 
1397a36c61f9SKrishna Gudipati void
1398a36c61f9SKrishna Gudipati bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
1399a36c61f9SKrishna Gudipati {
1400a36c61f9SKrishna Gudipati 	bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
1401a36c61f9SKrishna Gudipati }
1402