xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs.c (revision 973464fd)
152fa7bf9SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
27725ccfdSJing Huang /*
3889d0d42SAnil Gurumurthy  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
4889d0d42SAnil Gurumurthy  * Copyright (c) 2014- QLogic Corporation.
57725ccfdSJing Huang  * All rights reserved
6889d0d42SAnil Gurumurthy  * www.qlogic.com
77725ccfdSJing Huang  *
831e1d569SAnil Gurumurthy  * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
97725ccfdSJing Huang  */
107725ccfdSJing Huang 
115fbe25c7SJing Huang /*
127725ccfdSJing Huang  *  bfa_fcs.c BFA FCS main
137725ccfdSJing Huang  */
147725ccfdSJing Huang 
15f16a1750SMaggie Zhang #include "bfad_drv.h"
167826f304SKrishna Gudipati #include "bfad_im.h"
17a36c61f9SKrishna Gudipati #include "bfa_fcs.h"
18a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h"
19a36c61f9SKrishna Gudipati 
20a36c61f9SKrishna Gudipati BFA_TRC_FILE(FCS, FCS);
217725ccfdSJing Huang 
225fbe25c7SJing Huang /*
237725ccfdSJing Huang  *  fcs_api BFA FCS API
247725ccfdSJing Huang  */
257725ccfdSJing Huang 
267725ccfdSJing Huang static void
bfa_fcs_exit_comp(void * fcs_cbarg)277725ccfdSJing Huang bfa_fcs_exit_comp(void *fcs_cbarg)
287725ccfdSJing Huang {
297725ccfdSJing Huang 	struct bfa_fcs_s      *fcs = fcs_cbarg;
307725ccfdSJing Huang 	struct bfad_s         *bfad = fcs->bfad;
317725ccfdSJing Huang 
327725ccfdSJing Huang 	complete(&bfad->comp);
337725ccfdSJing Huang }
347725ccfdSJing Huang 
355fbe25c7SJing Huang /*
3682794a2eSKrishna Gudipati  * fcs initialization, called once after bfa initialization is complete
3782794a2eSKrishna Gudipati  */
3882794a2eSKrishna Gudipati void
bfa_fcs_init(struct bfa_fcs_s * fcs)3982794a2eSKrishna Gudipati bfa_fcs_init(struct bfa_fcs_s *fcs)
4082794a2eSKrishna Gudipati {
41984dc46cSChristoph Hellwig 	bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
42984dc46cSChristoph Hellwig 	bfa_trc(fcs, 0);
43984dc46cSChristoph Hellwig }
4482794a2eSKrishna Gudipati 
45984dc46cSChristoph Hellwig /*
46984dc46cSChristoph Hellwig  *  fcs_api BFA FCS API
47984dc46cSChristoph Hellwig  */
4875332a70SKrishna Gudipati 
4975332a70SKrishna Gudipati /*
5075332a70SKrishna Gudipati  * FCS update cfg - reset the pwwn/nwwn of fabric base logical port
5175332a70SKrishna Gudipati  * with values learned during bfa_init firmware GETATTR REQ.
5275332a70SKrishna Gudipati  */
5375332a70SKrishna Gudipati void
bfa_fcs_update_cfg(struct bfa_fcs_s * fcs)5475332a70SKrishna Gudipati bfa_fcs_update_cfg(struct bfa_fcs_s *fcs)
5575332a70SKrishna Gudipati {
5675332a70SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = &fcs->fabric;
5775332a70SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
5875332a70SKrishna Gudipati 	struct bfa_ioc_s *ioc = &fabric->fcs->bfa->ioc;
5975332a70SKrishna Gudipati 
6075332a70SKrishna Gudipati 	port_cfg->nwwn = ioc->attr->nwwn;
6175332a70SKrishna Gudipati 	port_cfg->pwwn = ioc->attr->pwwn;
6275332a70SKrishna Gudipati }
6375332a70SKrishna Gudipati 
6475332a70SKrishna Gudipati /*
65881c1b3cSKrishna Gudipati  * Stop FCS operations.
66881c1b3cSKrishna Gudipati  */
67881c1b3cSKrishna Gudipati void
bfa_fcs_stop(struct bfa_fcs_s * fcs)68881c1b3cSKrishna Gudipati bfa_fcs_stop(struct bfa_fcs_s *fcs)
69881c1b3cSKrishna Gudipati {
70881c1b3cSKrishna Gudipati 	bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
71881c1b3cSKrishna Gudipati 	bfa_wc_up(&fcs->wc);
72881c1b3cSKrishna Gudipati 	bfa_fcs_fabric_modstop(fcs);
73881c1b3cSKrishna Gudipati 	bfa_wc_wait(&fcs->wc);
74881c1b3cSKrishna Gudipati }
75881c1b3cSKrishna Gudipati 
76881c1b3cSKrishna Gudipati /*
7775332a70SKrishna Gudipati  * fcs pbc vport initialization
7875332a70SKrishna Gudipati  */
7975332a70SKrishna Gudipati void
bfa_fcs_pbc_vport_init(struct bfa_fcs_s * fcs)8075332a70SKrishna Gudipati bfa_fcs_pbc_vport_init(struct bfa_fcs_s *fcs)
8175332a70SKrishna Gudipati {
8275332a70SKrishna Gudipati 	int i, npbc_vports;
8375332a70SKrishna Gudipati 	struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];
8475332a70SKrishna Gudipati 
85d9883548SJing Huang 	/* Initialize pbc vports */
86d9883548SJing Huang 	if (!fcs->min_cfg) {
87d9883548SJing Huang 		npbc_vports =
88d9883548SJing Huang 			bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
89d9883548SJing Huang 		for (i = 0; i < npbc_vports; i++)
90d9883548SJing Huang 			bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
91d9883548SJing Huang 	}
927725ccfdSJing Huang }
937725ccfdSJing Huang 
945fbe25c7SJing Huang /*
95a36c61f9SKrishna Gudipati  *	brief
967725ccfdSJing Huang  *		FCS driver details initialization.
977725ccfdSJing Huang  *
987725ccfdSJing Huang  *	param[in]		fcs		FCS instance
997725ccfdSJing Huang  *	param[in]		driver_info	Driver Details
1007725ccfdSJing Huang  *
1017725ccfdSJing Huang  *	return None
1027725ccfdSJing Huang  */
1037725ccfdSJing Huang void
bfa_fcs_driver_info_init(struct bfa_fcs_s * fcs,struct bfa_fcs_driver_info_s * driver_info)1047725ccfdSJing Huang bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
1057725ccfdSJing Huang 			struct bfa_fcs_driver_info_s *driver_info)
1067725ccfdSJing Huang {
1077725ccfdSJing Huang 
1087725ccfdSJing Huang 	fcs->driver_info = *driver_info;
1097725ccfdSJing Huang 
1107725ccfdSJing Huang 	bfa_fcs_fabric_psymb_init(&fcs->fabric);
111ce7242b8SKrishna Gudipati 	bfa_fcs_fabric_nsymb_init(&fcs->fabric);
1127725ccfdSJing Huang }
1137725ccfdSJing Huang 
1145fbe25c7SJing Huang /*
115a36c61f9SKrishna Gudipati  *	brief
1167725ccfdSJing Huang  *		FCS instance cleanup and exit.
1177725ccfdSJing Huang  *
1187725ccfdSJing Huang  *	param[in]		fcs			FCS instance
1197725ccfdSJing Huang  *	return None
1207725ccfdSJing Huang  */
1217725ccfdSJing Huang void
bfa_fcs_exit(struct bfa_fcs_s * fcs)1227725ccfdSJing Huang bfa_fcs_exit(struct bfa_fcs_s *fcs)
1237725ccfdSJing Huang {
1247725ccfdSJing Huang 	bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
12582794a2eSKrishna Gudipati 	bfa_wc_up(&fcs->wc);
126984dc46cSChristoph Hellwig 	bfa_trc(fcs, 0);
127984dc46cSChristoph Hellwig 	bfa_lps_delete(fcs->fabric.lps);
128984dc46cSChristoph Hellwig 	bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_DELETE);
1297725ccfdSJing Huang 	bfa_wc_wait(&fcs->wc);
1307725ccfdSJing Huang }
1317725ccfdSJing Huang 
1325fbe25c7SJing Huang /*
133a36c61f9SKrishna Gudipati  * Fabric module implementation.
134a36c61f9SKrishna Gudipati  */
1357725ccfdSJing Huang 
136a36c61f9SKrishna Gudipati #define BFA_FCS_FABRIC_RETRY_DELAY	(2000)	/* Milliseconds */
137a36c61f9SKrishna Gudipati #define BFA_FCS_FABRIC_CLEANUP_DELAY	(10000)	/* Milliseconds */
138a36c61f9SKrishna Gudipati 
139a36c61f9SKrishna Gudipati #define bfa_fcs_fabric_set_opertype(__fabric) do {			\
140a36c61f9SKrishna Gudipati 	if (bfa_fcport_get_topology((__fabric)->fcs->bfa)		\
141d7be54ccSKrishna Gudipati 				== BFA_PORT_TOPOLOGY_P2P) {		\
142d7be54ccSKrishna Gudipati 		if (fabric->fab_type == BFA_FCS_FABRIC_SWITCHED)	\
143a36c61f9SKrishna Gudipati 			(__fabric)->oper_type = BFA_PORT_TYPE_NPORT;	\
144a36c61f9SKrishna Gudipati 		else							\
145d7be54ccSKrishna Gudipati 			(__fabric)->oper_type = BFA_PORT_TYPE_P2P;	\
146d7be54ccSKrishna Gudipati 	} else								\
147a36c61f9SKrishna Gudipati 		(__fabric)->oper_type = BFA_PORT_TYPE_NLPORT;		\
148a36c61f9SKrishna Gudipati } while (0)
149a36c61f9SKrishna Gudipati 
150a36c61f9SKrishna Gudipati /*
151a36c61f9SKrishna Gudipati  * forward declarations
152a36c61f9SKrishna Gudipati  */
153a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
154a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
155a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
156a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
157a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delay(void *cbarg);
158a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
159a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_delete_comp(void *cbarg);
160881c1b3cSKrishna Gudipati static void bfa_fcs_fabric_stop(struct bfa_fcs_fabric_s *fabric);
161881c1b3cSKrishna Gudipati static void bfa_fcs_fabric_stop_comp(void *cbarg);
162a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
163a36c61f9SKrishna Gudipati 				      struct fchs_s *fchs, u16 len);
164a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
165a36c61f9SKrishna Gudipati 					 struct fchs_s *fchs, u16 len);
166a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
167a36c61f9SKrishna Gudipati static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
168a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp, void *cbarg,
169a36c61f9SKrishna Gudipati 					 bfa_status_t status,
170a36c61f9SKrishna Gudipati 					 u32 rsp_len,
171a36c61f9SKrishna Gudipati 					 u32 resid_len,
172a36c61f9SKrishna Gudipati 					 struct fchs_s *rspfchs);
173a36c61f9SKrishna Gudipati 
174a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
175a36c61f9SKrishna Gudipati 					 enum bfa_fcs_fabric_event event);
176a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
177a36c61f9SKrishna Gudipati 					  enum bfa_fcs_fabric_event event);
178a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
179a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
180a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
181a36c61f9SKrishna Gudipati 					enum bfa_fcs_fabric_event event);
182a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
183a36c61f9SKrishna Gudipati 					      enum bfa_fcs_fabric_event event);
184a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
185a36c61f9SKrishna Gudipati 				       enum bfa_fcs_fabric_event event);
186a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
187a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
188a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
189a36c61f9SKrishna Gudipati 				       enum bfa_fcs_fabric_event event);
190a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
191a36c61f9SKrishna Gudipati 					    enum bfa_fcs_fabric_event event);
192a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
193a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
194a36c61f9SKrishna Gudipati static void	bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
195a36c61f9SKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
196881c1b3cSKrishna Gudipati static void	bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric,
197881c1b3cSKrishna Gudipati 					   enum bfa_fcs_fabric_event event);
198881c1b3cSKrishna Gudipati static void	bfa_fcs_fabric_sm_cleanup(struct bfa_fcs_fabric_s *fabric,
199881c1b3cSKrishna Gudipati 					  enum bfa_fcs_fabric_event event);
2005fbe25c7SJing Huang /*
201a36c61f9SKrishna Gudipati  *   Beginning state before fabric creation.
202a36c61f9SKrishna Gudipati  */
203a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)204a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
205a36c61f9SKrishna Gudipati 			 enum bfa_fcs_fabric_event event)
206a36c61f9SKrishna Gudipati {
207a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
208a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
209a36c61f9SKrishna Gudipati 
210a36c61f9SKrishna Gudipati 	switch (event) {
211a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CREATE:
212a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
213a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_init(fabric);
214a36c61f9SKrishna Gudipati 		bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
215a36c61f9SKrishna Gudipati 		break;
216a36c61f9SKrishna Gudipati 
217a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
218a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
219a36c61f9SKrishna Gudipati 		break;
220a36c61f9SKrishna Gudipati 
221a36c61f9SKrishna Gudipati 	default:
222a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
223a36c61f9SKrishna Gudipati 	}
224a36c61f9SKrishna Gudipati }
225a36c61f9SKrishna Gudipati 
2265fbe25c7SJing Huang /*
227a36c61f9SKrishna Gudipati  *   Beginning state before fabric creation.
228a36c61f9SKrishna Gudipati  */
229a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)230a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
231a36c61f9SKrishna Gudipati 			  enum bfa_fcs_fabric_event event)
232a36c61f9SKrishna Gudipati {
233bc0e2c2aSKrishna Gudipati 	struct bfa_s	*bfa = fabric->fcs->bfa;
234bc0e2c2aSKrishna Gudipati 
235a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
236a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
237a36c61f9SKrishna Gudipati 
238a36c61f9SKrishna Gudipati 	switch (event) {
239a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_START:
240bc0e2c2aSKrishna Gudipati 		if (!bfa_fcport_is_linkup(fabric->fcs->bfa)) {
241bc0e2c2aSKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
242bc0e2c2aSKrishna Gudipati 			break;
243bc0e2c2aSKrishna Gudipati 		}
244bc0e2c2aSKrishna Gudipati 		if (bfa_fcport_get_topology(bfa) ==
245bc0e2c2aSKrishna Gudipati 				BFA_PORT_TOPOLOGY_LOOP) {
246bc0e2c2aSKrishna Gudipati 			fabric->fab_type = BFA_FCS_FABRIC_LOOP;
247bc0e2c2aSKrishna Gudipati 			fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
248bc0e2c2aSKrishna Gudipati 			fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
249bc0e2c2aSKrishna Gudipati 			bfa_sm_set_state(fabric,
250bc0e2c2aSKrishna Gudipati 					bfa_fcs_fabric_sm_online);
251bc0e2c2aSKrishna Gudipati 			bfa_fcs_fabric_set_opertype(fabric);
252bc0e2c2aSKrishna Gudipati 			bfa_fcs_lport_online(&fabric->bport);
253bc0e2c2aSKrishna Gudipati 		} else {
254a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
255a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_login(fabric);
256bc0e2c2aSKrishna Gudipati 		}
257a36c61f9SKrishna Gudipati 		break;
258a36c61f9SKrishna Gudipati 
259a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
260a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
261a36c61f9SKrishna Gudipati 		break;
262a36c61f9SKrishna Gudipati 
263a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
264dd5aaf45SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
265dd5aaf45SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
266a36c61f9SKrishna Gudipati 		break;
267a36c61f9SKrishna Gudipati 
268a36c61f9SKrishna Gudipati 	default:
269a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
270a36c61f9SKrishna Gudipati 	}
271a36c61f9SKrishna Gudipati }
272a36c61f9SKrishna Gudipati 
2735fbe25c7SJing Huang /*
274a36c61f9SKrishna Gudipati  *   Link is down, awaiting LINK UP event from port. This is also the
275a36c61f9SKrishna Gudipati  *   first state at fabric creation.
276a36c61f9SKrishna Gudipati  */
277a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)278a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
279a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
280a36c61f9SKrishna Gudipati {
281bc0e2c2aSKrishna Gudipati 	struct bfa_s	*bfa = fabric->fcs->bfa;
282bc0e2c2aSKrishna Gudipati 
283a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
284a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
285a36c61f9SKrishna Gudipati 
286a36c61f9SKrishna Gudipati 	switch (event) {
287a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
288bc0e2c2aSKrishna Gudipati 		if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) {
289a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
290a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_login(fabric);
291a36c61f9SKrishna Gudipati 			break;
292bc0e2c2aSKrishna Gudipati 		}
293bc0e2c2aSKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_LOOP;
294bc0e2c2aSKrishna Gudipati 		fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
295bc0e2c2aSKrishna Gudipati 		fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
296bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
297bc0e2c2aSKrishna Gudipati 		bfa_fcs_fabric_set_opertype(fabric);
298bc0e2c2aSKrishna Gudipati 		bfa_fcs_lport_online(&fabric->bport);
299bc0e2c2aSKrishna Gudipati 		break;
300a36c61f9SKrishna Gudipati 
301a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
302bc0e2c2aSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LOOPBACK:
303a36c61f9SKrishna Gudipati 		break;
304a36c61f9SKrishna Gudipati 
305a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
306a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
307a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
308a36c61f9SKrishna Gudipati 		break;
309a36c61f9SKrishna Gudipati 
310881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_STOP:
311881c1b3cSKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
312881c1b3cSKrishna Gudipati 		bfa_fcs_fabric_stop(fabric);
313881c1b3cSKrishna Gudipati 		break;
314881c1b3cSKrishna Gudipati 
315a36c61f9SKrishna Gudipati 	default:
316a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
317a36c61f9SKrishna Gudipati 	}
318a36c61f9SKrishna Gudipati }
319a36c61f9SKrishna Gudipati 
3205fbe25c7SJing Huang /*
321a36c61f9SKrishna Gudipati  *   FLOGI is in progress, awaiting FLOGI reply.
322a36c61f9SKrishna Gudipati  */
323a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)324a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
325a36c61f9SKrishna Gudipati 			enum bfa_fcs_fabric_event event)
326a36c61f9SKrishna Gudipati {
327a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
328a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
329a36c61f9SKrishna Gudipati 
330a36c61f9SKrishna Gudipati 	switch (event) {
331a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CONT_OP:
332a36c61f9SKrishna Gudipati 
333a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
334bbe37a67SVijaya Mohan Guvva 					   fabric->bb_credit);
335a36c61f9SKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
336a36c61f9SKrishna Gudipati 
337a36c61f9SKrishna Gudipati 		if (fabric->auth_reqd && fabric->is_auth) {
338a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth);
339a36c61f9SKrishna Gudipati 			bfa_trc(fabric->fcs, event);
340a36c61f9SKrishna Gudipati 		} else {
341a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
342a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_notify_online(fabric);
343a36c61f9SKrishna Gudipati 		}
344a36c61f9SKrishna Gudipati 		break;
345a36c61f9SKrishna Gudipati 
346a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
347a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry);
348a36c61f9SKrishna Gudipati 		bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer,
349a36c61f9SKrishna Gudipati 				bfa_fcs_fabric_delay, fabric,
350a36c61f9SKrishna Gudipati 				BFA_FCS_FABRIC_RETRY_DELAY);
351a36c61f9SKrishna Gudipati 		break;
352a36c61f9SKrishna Gudipati 
353a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LOOPBACK:
354a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
355f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
356a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_set_opertype(fabric);
357a36c61f9SKrishna Gudipati 		break;
358a36c61f9SKrishna Gudipati 
359a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
360a36c61f9SKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_N2N;
361a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
362bbe37a67SVijaya Mohan Guvva 					   fabric->bb_credit);
363a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_online(fabric);
364a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
365a36c61f9SKrishna Gudipati 		break;
366a36c61f9SKrishna Gudipati 
367a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
368a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
369f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
370a36c61f9SKrishna Gudipati 		break;
371a36c61f9SKrishna Gudipati 
372a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
373a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
374f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
375a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
376a36c61f9SKrishna Gudipati 		break;
377a36c61f9SKrishna Gudipati 
378a36c61f9SKrishna Gudipati 	default:
379a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
380a36c61f9SKrishna Gudipati 	}
381a36c61f9SKrishna Gudipati }
382a36c61f9SKrishna Gudipati 
383a36c61f9SKrishna Gudipati 
384a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)385a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
386a36c61f9SKrishna Gudipati 			      enum bfa_fcs_fabric_event event)
387a36c61f9SKrishna Gudipati {
388a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
389a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
390a36c61f9SKrishna Gudipati 
391a36c61f9SKrishna Gudipati 	switch (event) {
392a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELAYED:
393a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
394a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_login(fabric);
395a36c61f9SKrishna Gudipati 		break;
396a36c61f9SKrishna Gudipati 
397a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
398a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
399a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fabric->delay_timer);
400a36c61f9SKrishna Gudipati 		break;
401a36c61f9SKrishna Gudipati 
402a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
403a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
404a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fabric->delay_timer);
405a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
406a36c61f9SKrishna Gudipati 		break;
407a36c61f9SKrishna Gudipati 
408a36c61f9SKrishna Gudipati 	default:
409a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
410a36c61f9SKrishna Gudipati 	}
411a36c61f9SKrishna Gudipati }
412a36c61f9SKrishna Gudipati 
4135fbe25c7SJing Huang /*
414a36c61f9SKrishna Gudipati  *   Authentication is in progress, awaiting authentication results.
415a36c61f9SKrishna Gudipati  */
416a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)417a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
418a36c61f9SKrishna Gudipati 		       enum bfa_fcs_fabric_event event)
419a36c61f9SKrishna Gudipati {
420a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
421a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
422a36c61f9SKrishna Gudipati 
423a36c61f9SKrishna Gudipati 	switch (event) {
424a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_FAILED:
425a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
426f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
427a36c61f9SKrishna Gudipati 		break;
428a36c61f9SKrishna Gudipati 
429a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
430a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
431a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_online(fabric);
432a36c61f9SKrishna Gudipati 		break;
433a36c61f9SKrishna Gudipati 
434a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_PERF_EVFP:
435a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp);
436a36c61f9SKrishna Gudipati 		break;
437a36c61f9SKrishna Gudipati 
438a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
439a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
440f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
441a36c61f9SKrishna Gudipati 		break;
442a36c61f9SKrishna Gudipati 
443a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
444a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
445a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
446a36c61f9SKrishna Gudipati 		break;
447a36c61f9SKrishna Gudipati 
448a36c61f9SKrishna Gudipati 	default:
449a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
450a36c61f9SKrishna Gudipati 	}
451a36c61f9SKrishna Gudipati }
452a36c61f9SKrishna Gudipati 
4535fbe25c7SJing Huang /*
454a36c61f9SKrishna Gudipati  *   Authentication failed
455a36c61f9SKrishna Gudipati  */
456f7f73812SMaggie Zhang void
bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)457a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
458a36c61f9SKrishna Gudipati 			      enum bfa_fcs_fabric_event event)
459a36c61f9SKrishna Gudipati {
460a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
461a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
462a36c61f9SKrishna Gudipati 
463a36c61f9SKrishna Gudipati 	switch (event) {
464a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
465a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
466a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
467a36c61f9SKrishna Gudipati 		break;
468a36c61f9SKrishna Gudipati 
469a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
470a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
471a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
472a36c61f9SKrishna Gudipati 		break;
473a36c61f9SKrishna Gudipati 
474a36c61f9SKrishna Gudipati 	default:
475a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
476a36c61f9SKrishna Gudipati 	}
477a36c61f9SKrishna Gudipati }
478a36c61f9SKrishna Gudipati 
4795fbe25c7SJing Huang /*
480a36c61f9SKrishna Gudipati  *   Port is in loopback mode.
481a36c61f9SKrishna Gudipati  */
482f7f73812SMaggie Zhang void
bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)483a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
484a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
485a36c61f9SKrishna Gudipati {
486a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
487a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
488a36c61f9SKrishna Gudipati 
489a36c61f9SKrishna Gudipati 	switch (event) {
490a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
491a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
492a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
493a36c61f9SKrishna Gudipati 		break;
494a36c61f9SKrishna Gudipati 
495a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
496a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
497a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
498a36c61f9SKrishna Gudipati 		break;
499a36c61f9SKrishna Gudipati 
500a36c61f9SKrishna Gudipati 	default:
501a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
502a36c61f9SKrishna Gudipati 	}
503a36c61f9SKrishna Gudipati }
504a36c61f9SKrishna Gudipati 
5055fbe25c7SJing Huang /*
506a36c61f9SKrishna Gudipati  *   There is no attached fabric - private loop or NPort-to-NPort topology.
507a36c61f9SKrishna Gudipati  */
508a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)509a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
510a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
511a36c61f9SKrishna Gudipati {
512a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
513a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
514a36c61f9SKrishna Gudipati 
515a36c61f9SKrishna Gudipati 	switch (event) {
516a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
517a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
518f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
519a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
520a36c61f9SKrishna Gudipati 		break;
521a36c61f9SKrishna Gudipati 
522a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
523a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
524a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
525a36c61f9SKrishna Gudipati 		break;
526a36c61f9SKrishna Gudipati 
527a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
528a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, fabric->bb_credit);
529a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
530bbe37a67SVijaya Mohan Guvva 					   fabric->bb_credit);
531a36c61f9SKrishna Gudipati 		break;
532a36c61f9SKrishna Gudipati 
533d7be54ccSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_RETRY_OP:
534d7be54ccSKrishna Gudipati 		break;
535d7be54ccSKrishna Gudipati 
536a36c61f9SKrishna Gudipati 	default:
537a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
538a36c61f9SKrishna Gudipati 	}
539a36c61f9SKrishna Gudipati }
540a36c61f9SKrishna Gudipati 
5415fbe25c7SJing Huang /*
542a36c61f9SKrishna Gudipati  *   Fabric is online - normal operating state.
543a36c61f9SKrishna Gudipati  */
544f7f73812SMaggie Zhang void
bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)545a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
546a36c61f9SKrishna Gudipati 			 enum bfa_fcs_fabric_event event)
547a36c61f9SKrishna Gudipati {
548bc0e2c2aSKrishna Gudipati 	struct bfa_s	*bfa = fabric->fcs->bfa;
549bc0e2c2aSKrishna Gudipati 
550a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
551a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
552a36c61f9SKrishna Gudipati 
553a36c61f9SKrishna Gudipati 	switch (event) {
554a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
555a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
556bc0e2c2aSKrishna Gudipati 		if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
557bc0e2c2aSKrishna Gudipati 			bfa_fcs_lport_offline(&fabric->bport);
558bc0e2c2aSKrishna Gudipati 		} else {
559f7f73812SMaggie Zhang 			bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
560a36c61f9SKrishna Gudipati 			bfa_fcs_fabric_notify_offline(fabric);
561bc0e2c2aSKrishna Gudipati 		}
562a36c61f9SKrishna Gudipati 		break;
563a36c61f9SKrishna Gudipati 
564a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELETE:
565a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
566a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_delete(fabric);
567a36c61f9SKrishna Gudipati 		break;
568a36c61f9SKrishna Gudipati 
569881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_STOP:
570881c1b3cSKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_stopping);
571881c1b3cSKrishna Gudipati 		bfa_fcs_fabric_stop(fabric);
572881c1b3cSKrishna Gudipati 		break;
573881c1b3cSKrishna Gudipati 
574a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_FAILED:
575a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
576f7f73812SMaggie Zhang 		bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
577a36c61f9SKrishna Gudipati 		break;
578a36c61f9SKrishna Gudipati 
579a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
580a36c61f9SKrishna Gudipati 		break;
581a36c61f9SKrishna Gudipati 
582a36c61f9SKrishna Gudipati 	default:
583a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
584a36c61f9SKrishna Gudipati 	}
585a36c61f9SKrishna Gudipati }
586a36c61f9SKrishna Gudipati 
5875fbe25c7SJing Huang /*
588a36c61f9SKrishna Gudipati  *   Exchanging virtual fabric parameters.
589a36c61f9SKrishna Gudipati  */
590a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)591a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
592a36c61f9SKrishna Gudipati 		       enum bfa_fcs_fabric_event event)
593a36c61f9SKrishna Gudipati {
594a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
595a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
596a36c61f9SKrishna Gudipati 
597a36c61f9SKrishna Gudipati 	switch (event) {
598a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_CONT_OP:
599a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done);
600a36c61f9SKrishna Gudipati 		break;
601a36c61f9SKrishna Gudipati 
602a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_ISOLATE:
603a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated);
604a36c61f9SKrishna Gudipati 		break;
605a36c61f9SKrishna Gudipati 
606a36c61f9SKrishna Gudipati 	default:
607a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
608a36c61f9SKrishna Gudipati 	}
609a36c61f9SKrishna Gudipati }
610a36c61f9SKrishna Gudipati 
6115fbe25c7SJing Huang /*
612a36c61f9SKrishna Gudipati  *   EVFP exchange complete and VFT tagging is enabled.
613a36c61f9SKrishna Gudipati  */
614a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)615a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
616a36c61f9SKrishna Gudipati 			    enum bfa_fcs_fabric_event event)
617a36c61f9SKrishna Gudipati {
618a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
619a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
620a36c61f9SKrishna Gudipati }
621a36c61f9SKrishna Gudipati 
6225fbe25c7SJing Huang /*
623a36c61f9SKrishna Gudipati  *   Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
624a36c61f9SKrishna Gudipati  */
625a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)626a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
627a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
628a36c61f9SKrishna Gudipati {
629a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
630a36c61f9SKrishna Gudipati 	char	pwwn_ptr[BFA_STRING_32];
631a36c61f9SKrishna Gudipati 
632a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
633a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
634a36c61f9SKrishna Gudipati 	wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn);
635a36c61f9SKrishna Gudipati 
63688166242SJing Huang 	BFA_LOG(KERN_INFO, bfad, bfa_log_level,
637a36c61f9SKrishna Gudipati 		"Port is isolated due to VF_ID mismatch. "
638a36c61f9SKrishna Gudipati 		"PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.",
639a36c61f9SKrishna Gudipati 		pwwn_ptr, fabric->fcs->port_vfid,
640a36c61f9SKrishna Gudipati 		fabric->event_arg.swp_vfid);
641a36c61f9SKrishna Gudipati }
642a36c61f9SKrishna Gudipati 
6435fbe25c7SJing Huang /*
644a36c61f9SKrishna Gudipati  *   Fabric is being deleted, awaiting vport delete completions.
645a36c61f9SKrishna Gudipati  */
646a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)647a36c61f9SKrishna Gudipati bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
648a36c61f9SKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
649a36c61f9SKrishna Gudipati {
650a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
651a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, event);
652a36c61f9SKrishna Gudipati 
653a36c61f9SKrishna Gudipati 	switch (event) {
654a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_DELCOMP:
655a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
656f7f73812SMaggie Zhang 		bfa_wc_down(&fabric->fcs->wc);
657a36c61f9SKrishna Gudipati 		break;
658a36c61f9SKrishna Gudipati 
659a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
660a36c61f9SKrishna Gudipati 		break;
661a36c61f9SKrishna Gudipati 
662a36c61f9SKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
663a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_notify_offline(fabric);
664a36c61f9SKrishna Gudipati 		break;
665a36c61f9SKrishna Gudipati 
666a36c61f9SKrishna Gudipati 	default:
667a36c61f9SKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
668a36c61f9SKrishna Gudipati 	}
669a36c61f9SKrishna Gudipati }
670a36c61f9SKrishna Gudipati 
671881c1b3cSKrishna Gudipati /*
672881c1b3cSKrishna Gudipati  * Fabric is being stopped, awaiting vport stop completions.
673881c1b3cSKrishna Gudipati  */
674881c1b3cSKrishna Gudipati static void
bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)675881c1b3cSKrishna Gudipati bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric,
676881c1b3cSKrishna Gudipati 			   enum bfa_fcs_fabric_event event)
677881c1b3cSKrishna Gudipati {
678bc0e2c2aSKrishna Gudipati 	struct bfa_s	*bfa = fabric->fcs->bfa;
679bc0e2c2aSKrishna Gudipati 
680881c1b3cSKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
681881c1b3cSKrishna Gudipati 	bfa_trc(fabric->fcs, event);
682a36c61f9SKrishna Gudipati 
683881c1b3cSKrishna Gudipati 	switch (event) {
684881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_STOPCOMP:
685bc0e2c2aSKrishna Gudipati 		if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
686bc0e2c2aSKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
687bc0e2c2aSKrishna Gudipati 		} else {
688881c1b3cSKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
689881c1b3cSKrishna Gudipati 			bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT);
690bc0e2c2aSKrishna Gudipati 		}
691881c1b3cSKrishna Gudipati 		break;
692881c1b3cSKrishna Gudipati 
693881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_UP:
694881c1b3cSKrishna Gudipati 		break;
695881c1b3cSKrishna Gudipati 
696881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
697bc0e2c2aSKrishna Gudipati 		if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
698bc0e2c2aSKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
699bc0e2c2aSKrishna Gudipati 		else
700881c1b3cSKrishna Gudipati 			bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
701881c1b3cSKrishna Gudipati 		break;
702881c1b3cSKrishna Gudipati 
703881c1b3cSKrishna Gudipati 	default:
704881c1b3cSKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
705881c1b3cSKrishna Gudipati 	}
706881c1b3cSKrishna Gudipati }
707881c1b3cSKrishna Gudipati 
708881c1b3cSKrishna Gudipati /*
709881c1b3cSKrishna Gudipati  * Fabric is being stopped, cleanup without FLOGO
710881c1b3cSKrishna Gudipati  */
711881c1b3cSKrishna Gudipati static void
bfa_fcs_fabric_sm_cleanup(struct bfa_fcs_fabric_s * fabric,enum bfa_fcs_fabric_event event)712881c1b3cSKrishna Gudipati bfa_fcs_fabric_sm_cleanup(struct bfa_fcs_fabric_s *fabric,
713881c1b3cSKrishna Gudipati 			  enum bfa_fcs_fabric_event event)
714881c1b3cSKrishna Gudipati {
715881c1b3cSKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
716881c1b3cSKrishna Gudipati 	bfa_trc(fabric->fcs, event);
717881c1b3cSKrishna Gudipati 
718881c1b3cSKrishna Gudipati 	switch (event) {
719881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_STOPCOMP:
720881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LOGOCOMP:
721881c1b3cSKrishna Gudipati 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
722881c1b3cSKrishna Gudipati 		bfa_wc_down(&(fabric->fcs)->wc);
723881c1b3cSKrishna Gudipati 		break;
724881c1b3cSKrishna Gudipati 
725881c1b3cSKrishna Gudipati 	case BFA_FCS_FABRIC_SM_LINK_DOWN:
726881c1b3cSKrishna Gudipati 		/*
727881c1b3cSKrishna Gudipati 		 * Ignore - can get this event if we get notified about IOC down
728881c1b3cSKrishna Gudipati 		 * before the fabric completion callbk is done.
729881c1b3cSKrishna Gudipati 		 */
730881c1b3cSKrishna Gudipati 		break;
731881c1b3cSKrishna Gudipati 
732881c1b3cSKrishna Gudipati 	default:
733881c1b3cSKrishna Gudipati 		bfa_sm_fault(fabric->fcs, event);
734881c1b3cSKrishna Gudipati 	}
735881c1b3cSKrishna Gudipati }
736a36c61f9SKrishna Gudipati 
7375fbe25c7SJing Huang /*
738a36c61f9SKrishna Gudipati  *  fcs_fabric_private fabric private functions
739a36c61f9SKrishna Gudipati  */
740a36c61f9SKrishna Gudipati 
741a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_init(struct bfa_fcs_fabric_s * fabric)742a36c61f9SKrishna Gudipati bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
743a36c61f9SKrishna Gudipati {
744a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
745a36c61f9SKrishna Gudipati 
746a36c61f9SKrishna Gudipati 	port_cfg->roles = BFA_LPORT_ROLE_FCP_IM;
747f7f73812SMaggie Zhang 	port_cfg->nwwn = fabric->fcs->bfa->ioc.attr->nwwn;
748f7f73812SMaggie Zhang 	port_cfg->pwwn = fabric->fcs->bfa->ioc.attr->pwwn;
749a36c61f9SKrishna Gudipati }
750a36c61f9SKrishna Gudipati 
7515fbe25c7SJing Huang /*
752a36c61f9SKrishna Gudipati  * Port Symbolic Name Creation for base port.
753a36c61f9SKrishna Gudipati  */
754a36c61f9SKrishna Gudipati void
bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s * fabric)755a36c61f9SKrishna Gudipati bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
756a36c61f9SKrishna Gudipati {
757a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
758a36c61f9SKrishna Gudipati 	char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
759a36c61f9SKrishna Gudipati 	struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
760a36c61f9SKrishna Gudipati 
761a36c61f9SKrishna Gudipati 	bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
762a36c61f9SKrishna Gudipati 
763a36c61f9SKrishna Gudipati 	/* Model name/number */
764*973464fdSAzeem Shaikh 	strscpy(port_cfg->sym_name.symname, model,
7658c5a50e8SArnd Bergmann 		BFA_SYMNAME_MAXLEN);
7668c5a50e8SArnd Bergmann 	strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
7678c5a50e8SArnd Bergmann 		BFA_SYMNAME_MAXLEN);
768a36c61f9SKrishna Gudipati 
769a36c61f9SKrishna Gudipati 	/* Driver Version */
7708c5a50e8SArnd Bergmann 	strlcat(port_cfg->sym_name.symname, driver_info->version,
7718c5a50e8SArnd Bergmann 		BFA_SYMNAME_MAXLEN);
7728c5a50e8SArnd Bergmann 	strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
7738c5a50e8SArnd Bergmann 		BFA_SYMNAME_MAXLEN);
774a36c61f9SKrishna Gudipati 
775a36c61f9SKrishna Gudipati 	/* Host machine name */
7768c5a50e8SArnd Bergmann 	strlcat(port_cfg->sym_name.symname,
7778c5a50e8SArnd Bergmann 		driver_info->host_machine_name,
7788c5a50e8SArnd Bergmann 		BFA_SYMNAME_MAXLEN);
7798c5a50e8SArnd Bergmann 	strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
7808c5a50e8SArnd Bergmann 		BFA_SYMNAME_MAXLEN);
781a36c61f9SKrishna Gudipati 
782a36c61f9SKrishna Gudipati 	/*
783a36c61f9SKrishna Gudipati 	 * Host OS Info :
784a36c61f9SKrishna Gudipati 	 * If OS Patch Info is not there, do not truncate any bytes from the
785a36c61f9SKrishna Gudipati 	 * OS name string and instead copy the entire OS info string (64 bytes).
786a36c61f9SKrishna Gudipati 	 */
787a36c61f9SKrishna Gudipati 	if (driver_info->host_os_patch[0] == '\0') {
7888c5a50e8SArnd Bergmann 		strlcat(port_cfg->sym_name.symname,
7898c5a50e8SArnd Bergmann 			driver_info->host_os_name,
7908c5a50e8SArnd Bergmann 			BFA_SYMNAME_MAXLEN);
7918c5a50e8SArnd Bergmann 		strlcat(port_cfg->sym_name.symname,
792a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
7938c5a50e8SArnd Bergmann 			BFA_SYMNAME_MAXLEN);
794a36c61f9SKrishna Gudipati 	} else {
7958c5a50e8SArnd Bergmann 		strlcat(port_cfg->sym_name.symname,
7968c5a50e8SArnd Bergmann 			driver_info->host_os_name,
7978c5a50e8SArnd Bergmann 			BFA_SYMNAME_MAXLEN);
7988c5a50e8SArnd Bergmann 		strlcat(port_cfg->sym_name.symname,
799a36c61f9SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
8008c5a50e8SArnd Bergmann 			BFA_SYMNAME_MAXLEN);
801a36c61f9SKrishna Gudipati 
802a36c61f9SKrishna Gudipati 		/* Append host OS Patch Info */
8038c5a50e8SArnd Bergmann 		strlcat(port_cfg->sym_name.symname,
8048c5a50e8SArnd Bergmann 			driver_info->host_os_patch,
8058c5a50e8SArnd Bergmann 			BFA_SYMNAME_MAXLEN);
806a36c61f9SKrishna Gudipati 	}
807a36c61f9SKrishna Gudipati 
808a36c61f9SKrishna Gudipati 	/* null terminate */
809a36c61f9SKrishna Gudipati 	port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
810a36c61f9SKrishna Gudipati }
811a36c61f9SKrishna Gudipati 
8125fbe25c7SJing Huang /*
813ce7242b8SKrishna Gudipati  * Node Symbolic Name Creation for base port and all vports
814ce7242b8SKrishna Gudipati  */
815ce7242b8SKrishna Gudipati void
bfa_fcs_fabric_nsymb_init(struct bfa_fcs_fabric_s * fabric)816ce7242b8SKrishna Gudipati bfa_fcs_fabric_nsymb_init(struct bfa_fcs_fabric_s *fabric)
817ce7242b8SKrishna Gudipati {
818ce7242b8SKrishna Gudipati 	struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
819ce7242b8SKrishna Gudipati 	char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
820ce7242b8SKrishna Gudipati 	struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
821ce7242b8SKrishna Gudipati 
822ce7242b8SKrishna Gudipati 	bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
823ce7242b8SKrishna Gudipati 
824ce7242b8SKrishna Gudipati 	/* Model name/number */
825*973464fdSAzeem Shaikh 	strscpy(port_cfg->node_sym_name.symname, model,
8268c5a50e8SArnd Bergmann 		BFA_SYMNAME_MAXLEN);
8278c5a50e8SArnd Bergmann 	strlcat(port_cfg->node_sym_name.symname,
828ce7242b8SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
8298c5a50e8SArnd Bergmann 			BFA_SYMNAME_MAXLEN);
830ce7242b8SKrishna Gudipati 
831ce7242b8SKrishna Gudipati 	/* Driver Version */
8328c5a50e8SArnd Bergmann 	strlcat(port_cfg->node_sym_name.symname, (char *)driver_info->version,
8338c5a50e8SArnd Bergmann 		BFA_SYMNAME_MAXLEN);
8348c5a50e8SArnd Bergmann 	strlcat(port_cfg->node_sym_name.symname,
835ce7242b8SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
8368c5a50e8SArnd Bergmann 			BFA_SYMNAME_MAXLEN);
837ce7242b8SKrishna Gudipati 
838ce7242b8SKrishna Gudipati 	/* Host machine name */
8398c5a50e8SArnd Bergmann 	strlcat(port_cfg->node_sym_name.symname,
8408c5a50e8SArnd Bergmann 		driver_info->host_machine_name,
8418c5a50e8SArnd Bergmann 		BFA_SYMNAME_MAXLEN);
8428c5a50e8SArnd Bergmann 	strlcat(port_cfg->node_sym_name.symname,
843ce7242b8SKrishna Gudipati 			BFA_FCS_PORT_SYMBNAME_SEPARATOR,
8448c5a50e8SArnd Bergmann 			BFA_SYMNAME_MAXLEN);
845ce7242b8SKrishna Gudipati 
846ce7242b8SKrishna Gudipati 	/* null terminate */
847ce7242b8SKrishna Gudipati 	port_cfg->node_sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
848ce7242b8SKrishna Gudipati }
849ce7242b8SKrishna Gudipati 
850ce7242b8SKrishna Gudipati /*
851a36c61f9SKrishna Gudipati  * bfa lps login completion callback
852a36c61f9SKrishna Gudipati  */
853a36c61f9SKrishna Gudipati void
bfa_cb_lps_flogi_comp(void * bfad,void * uarg,bfa_status_t status)854a36c61f9SKrishna Gudipati bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
855a36c61f9SKrishna Gudipati {
856a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = uarg;
857a36c61f9SKrishna Gudipati 
858a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
859a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, status);
860a36c61f9SKrishna Gudipati 
861a36c61f9SKrishna Gudipati 	switch (status) {
862a36c61f9SKrishna Gudipati 	case BFA_STATUS_OK:
863a36c61f9SKrishna Gudipati 		fabric->stats.flogi_accepts++;
864a36c61f9SKrishna Gudipati 		break;
865a36c61f9SKrishna Gudipati 
866a36c61f9SKrishna Gudipati 	case BFA_STATUS_INVALID_MAC:
867a36c61f9SKrishna Gudipati 		/* Only for CNA */
868a36c61f9SKrishna Gudipati 		fabric->stats.flogi_acc_err++;
869a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
870a36c61f9SKrishna Gudipati 
871a36c61f9SKrishna Gudipati 		return;
872a36c61f9SKrishna Gudipati 
873a36c61f9SKrishna Gudipati 	case BFA_STATUS_EPROTOCOL:
874f7f73812SMaggie Zhang 		switch (fabric->lps->ext_status) {
875a36c61f9SKrishna Gudipati 		case BFA_EPROTO_BAD_ACCEPT:
876a36c61f9SKrishna Gudipati 			fabric->stats.flogi_acc_err++;
877a36c61f9SKrishna Gudipati 			break;
878a36c61f9SKrishna Gudipati 
879a36c61f9SKrishna Gudipati 		case BFA_EPROTO_UNKNOWN_RSP:
880a36c61f9SKrishna Gudipati 			fabric->stats.flogi_unknown_rsp++;
881a36c61f9SKrishna Gudipati 			break;
882a36c61f9SKrishna Gudipati 
883a36c61f9SKrishna Gudipati 		default:
884a36c61f9SKrishna Gudipati 			break;
885a36c61f9SKrishna Gudipati 		}
886a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
887a36c61f9SKrishna Gudipati 
888a36c61f9SKrishna Gudipati 		return;
889a36c61f9SKrishna Gudipati 
890a36c61f9SKrishna Gudipati 	case BFA_STATUS_FABRIC_RJT:
891a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rejects++;
892a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
893a36c61f9SKrishna Gudipati 		return;
894a36c61f9SKrishna Gudipati 
895a36c61f9SKrishna Gudipati 	default:
896a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rsp_err++;
897a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
898a36c61f9SKrishna Gudipati 		return;
899a36c61f9SKrishna Gudipati 	}
900a36c61f9SKrishna Gudipati 
901f7f73812SMaggie Zhang 	fabric->bb_credit = fabric->lps->pr_bbcred;
902a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bb_credit);
903a36c61f9SKrishna Gudipati 
904f7f73812SMaggie Zhang 	if (!(fabric->lps->brcd_switch))
905f7f73812SMaggie Zhang 		fabric->fabric_name =  fabric->lps->pr_nwwn;
906a36c61f9SKrishna Gudipati 
907a36c61f9SKrishna Gudipati 	/*
908a36c61f9SKrishna Gudipati 	 * Check port type. It should be 1 = F-port.
909a36c61f9SKrishna Gudipati 	 */
910f7f73812SMaggie Zhang 	if (fabric->lps->fport) {
911f7f73812SMaggie Zhang 		fabric->bport.pid = fabric->lps->lp_pid;
912f7f73812SMaggie Zhang 		fabric->is_npiv = fabric->lps->npiv_en;
913f7f73812SMaggie Zhang 		fabric->is_auth = fabric->lps->auth_req;
914a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
915a36c61f9SKrishna Gudipati 	} else {
916a36c61f9SKrishna Gudipati 		/*
917a36c61f9SKrishna Gudipati 		 * Nport-2-Nport direct attached
918a36c61f9SKrishna Gudipati 		 */
919a36c61f9SKrishna Gudipati 		fabric->bport.port_topo.pn2n.rem_port_wwn =
920f7f73812SMaggie Zhang 			fabric->lps->pr_pwwn;
921d7be54ccSKrishna Gudipati 		fabric->fab_type = BFA_FCS_FABRIC_N2N;
922a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
923a36c61f9SKrishna Gudipati 	}
924a36c61f9SKrishna Gudipati 
925a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.pid);
926a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->is_npiv);
927a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->is_auth);
928a36c61f9SKrishna Gudipati }
9295fbe25c7SJing Huang /*
930a36c61f9SKrishna Gudipati  *		Allocate and send FLOGI.
931a36c61f9SKrishna Gudipati  */
932a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_login(struct bfa_fcs_fabric_s * fabric)933a36c61f9SKrishna Gudipati bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
934a36c61f9SKrishna Gudipati {
935a36c61f9SKrishna Gudipati 	struct bfa_s		*bfa = fabric->fcs->bfa;
936a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s	*pcfg = &fabric->bport.port_cfg;
937bbe37a67SVijaya Mohan Guvva 	u8			alpa = 0;
938a36c61f9SKrishna Gudipati 
939be540a99SKrishna Gudipati 
940a36c61f9SKrishna Gudipati 	bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
941bbe37a67SVijaya Mohan Guvva 		      pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
942a36c61f9SKrishna Gudipati 
943a36c61f9SKrishna Gudipati 	fabric->stats.flogi_sent++;
944a36c61f9SKrishna Gudipati }
945a36c61f9SKrishna Gudipati 
946a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s * fabric)947a36c61f9SKrishna Gudipati bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
948a36c61f9SKrishna Gudipati {
949a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
950a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
951a36c61f9SKrishna Gudipati 
952a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->fabric_name);
953a36c61f9SKrishna Gudipati 
954a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_set_opertype(fabric);
955a36c61f9SKrishna Gudipati 	fabric->stats.fabric_onlines++;
956a36c61f9SKrishna Gudipati 
9575fbe25c7SJing Huang 	/*
958a36c61f9SKrishna Gudipati 	 * notify online event to base and then virtual ports
959a36c61f9SKrishna Gudipati 	 */
960a36c61f9SKrishna Gudipati 	bfa_fcs_lport_online(&fabric->bport);
961a36c61f9SKrishna Gudipati 
962a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
963a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
964a36c61f9SKrishna Gudipati 		bfa_fcs_vport_online(vport);
965a36c61f9SKrishna Gudipati 	}
966a36c61f9SKrishna Gudipati }
967a36c61f9SKrishna Gudipati 
968a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s * fabric)969a36c61f9SKrishna Gudipati bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
970a36c61f9SKrishna Gudipati {
971a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
972a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
973a36c61f9SKrishna Gudipati 
974a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->fabric_name);
975a36c61f9SKrishna Gudipati 	fabric->stats.fabric_offlines++;
976a36c61f9SKrishna Gudipati 
9775fbe25c7SJing Huang 	/*
978a36c61f9SKrishna Gudipati 	 * notify offline event first to vports and then base port.
979a36c61f9SKrishna Gudipati 	 */
980a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
981a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
982a36c61f9SKrishna Gudipati 		bfa_fcs_vport_offline(vport);
983a36c61f9SKrishna Gudipati 	}
984a36c61f9SKrishna Gudipati 
985a36c61f9SKrishna Gudipati 	bfa_fcs_lport_offline(&fabric->bport);
986a36c61f9SKrishna Gudipati 
987a36c61f9SKrishna Gudipati 	fabric->fabric_name = 0;
988a36c61f9SKrishna Gudipati 	fabric->fabric_ip_addr[0] = 0;
989a36c61f9SKrishna Gudipati }
990a36c61f9SKrishna Gudipati 
991a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_delay(void * cbarg)992a36c61f9SKrishna Gudipati bfa_fcs_fabric_delay(void *cbarg)
993a36c61f9SKrishna Gudipati {
994a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
995a36c61f9SKrishna Gudipati 
996a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
997a36c61f9SKrishna Gudipati }
998a36c61f9SKrishna Gudipati 
9995fbe25c7SJing Huang /*
1000881c1b3cSKrishna Gudipati  * Stop all vports and wait for vport stop completions.
1001881c1b3cSKrishna Gudipati  */
1002881c1b3cSKrishna Gudipati static void
bfa_fcs_fabric_stop(struct bfa_fcs_fabric_s * fabric)1003881c1b3cSKrishna Gudipati bfa_fcs_fabric_stop(struct bfa_fcs_fabric_s *fabric)
1004881c1b3cSKrishna Gudipati {
1005881c1b3cSKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1006881c1b3cSKrishna Gudipati 	struct list_head	*qe, *qen;
1007881c1b3cSKrishna Gudipati 
1008881c1b3cSKrishna Gudipati 	bfa_wc_init(&fabric->stop_wc, bfa_fcs_fabric_stop_comp, fabric);
1009881c1b3cSKrishna Gudipati 
1010881c1b3cSKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
1011881c1b3cSKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1012881c1b3cSKrishna Gudipati 		bfa_wc_up(&fabric->stop_wc);
1013881c1b3cSKrishna Gudipati 		bfa_fcs_vport_fcs_stop(vport);
1014881c1b3cSKrishna Gudipati 	}
1015881c1b3cSKrishna Gudipati 
1016881c1b3cSKrishna Gudipati 	bfa_wc_up(&fabric->stop_wc);
1017881c1b3cSKrishna Gudipati 	bfa_fcs_lport_stop(&fabric->bport);
1018881c1b3cSKrishna Gudipati 	bfa_wc_wait(&fabric->stop_wc);
1019881c1b3cSKrishna Gudipati }
1020881c1b3cSKrishna Gudipati 
1021881c1b3cSKrishna Gudipati /*
1022a36c61f9SKrishna Gudipati  * Delete all vports and wait for vport delete completions.
1023a36c61f9SKrishna Gudipati  */
1024a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s * fabric)1025a36c61f9SKrishna Gudipati bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
1026a36c61f9SKrishna Gudipati {
1027a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1028a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
1029a36c61f9SKrishna Gudipati 
1030a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &fabric->vport_q) {
1031a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1032a36c61f9SKrishna Gudipati 		bfa_fcs_vport_fcs_delete(vport);
1033a36c61f9SKrishna Gudipati 	}
1034a36c61f9SKrishna Gudipati 
1035a36c61f9SKrishna Gudipati 	bfa_fcs_lport_delete(&fabric->bport);
1036a36c61f9SKrishna Gudipati 	bfa_wc_wait(&fabric->wc);
1037a36c61f9SKrishna Gudipati }
1038a36c61f9SKrishna Gudipati 
1039a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_delete_comp(void * cbarg)1040a36c61f9SKrishna Gudipati bfa_fcs_fabric_delete_comp(void *cbarg)
1041a36c61f9SKrishna Gudipati {
1042a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
1043a36c61f9SKrishna Gudipati 
1044a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
1045a36c61f9SKrishna Gudipati }
1046a36c61f9SKrishna Gudipati 
1047881c1b3cSKrishna Gudipati static void
bfa_fcs_fabric_stop_comp(void * cbarg)1048881c1b3cSKrishna Gudipati bfa_fcs_fabric_stop_comp(void *cbarg)
1049881c1b3cSKrishna Gudipati {
1050881c1b3cSKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
1051881c1b3cSKrishna Gudipati 
1052881c1b3cSKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_STOPCOMP);
1053881c1b3cSKrishna Gudipati }
1054881c1b3cSKrishna Gudipati 
10555fbe25c7SJing Huang /*
1056a36c61f9SKrishna Gudipati  *  fcs_fabric_public fabric public functions
1057a36c61f9SKrishna Gudipati  */
1058a36c61f9SKrishna Gudipati 
10595fbe25c7SJing Huang /*
1060881c1b3cSKrishna Gudipati  * Fabric module stop -- stop FCS actions
1061881c1b3cSKrishna Gudipati  */
1062881c1b3cSKrishna Gudipati void
bfa_fcs_fabric_modstop(struct bfa_fcs_s * fcs)1063881c1b3cSKrishna Gudipati bfa_fcs_fabric_modstop(struct bfa_fcs_s *fcs)
1064881c1b3cSKrishna Gudipati {
1065881c1b3cSKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1066881c1b3cSKrishna Gudipati 
1067881c1b3cSKrishna Gudipati 	bfa_trc(fcs, 0);
1068881c1b3cSKrishna Gudipati 	fabric = &fcs->fabric;
1069881c1b3cSKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_STOP);
1070881c1b3cSKrishna Gudipati }
1071881c1b3cSKrishna Gudipati 
1072881c1b3cSKrishna Gudipati /*
1073a36c61f9SKrishna Gudipati  * Fabric module start -- kick starts FCS actions
1074a36c61f9SKrishna Gudipati  */
1075a36c61f9SKrishna Gudipati void
bfa_fcs_fabric_modstart(struct bfa_fcs_s * fcs)1076a36c61f9SKrishna Gudipati bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
1077a36c61f9SKrishna Gudipati {
1078a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1079a36c61f9SKrishna Gudipati 
1080a36c61f9SKrishna Gudipati 	bfa_trc(fcs, 0);
1081a36c61f9SKrishna Gudipati 	fabric = &fcs->fabric;
1082a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
1083a36c61f9SKrishna Gudipati }
1084a36c61f9SKrishna Gudipati 
1085a36c61f9SKrishna Gudipati 
10865fbe25c7SJing Huang /*
1087a36c61f9SKrishna Gudipati  *   Link up notification from BFA physical port module.
1088a36c61f9SKrishna Gudipati  */
1089a36c61f9SKrishna Gudipati void
bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s * fabric)1090a36c61f9SKrishna Gudipati bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
1091a36c61f9SKrishna Gudipati {
1092a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
1093a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
1094a36c61f9SKrishna Gudipati }
1095a36c61f9SKrishna Gudipati 
10965fbe25c7SJing Huang /*
1097a36c61f9SKrishna Gudipati  *   Link down notification from BFA physical port module.
1098a36c61f9SKrishna Gudipati  */
1099a36c61f9SKrishna Gudipati void
bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s * fabric)1100a36c61f9SKrishna Gudipati bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
1101a36c61f9SKrishna Gudipati {
1102a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
1103a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
1104a36c61f9SKrishna Gudipati }
1105a36c61f9SKrishna Gudipati 
11065fbe25c7SJing Huang /*
1107a36c61f9SKrishna Gudipati  *   A child vport is being created in the fabric.
1108a36c61f9SKrishna Gudipati  *
1109a36c61f9SKrishna Gudipati  *   Call from vport module at vport creation. A list of base port and vports
1110a36c61f9SKrishna Gudipati  *   belonging to a fabric is maintained to propagate link events.
1111a36c61f9SKrishna Gudipati  *
1112a36c61f9SKrishna Gudipati  *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
1113a36c61f9SKrishna Gudipati  *   param[in] vport  - Vport being created.
1114a36c61f9SKrishna Gudipati  *
1115a36c61f9SKrishna Gudipati  *   @return None (always succeeds)
1116a36c61f9SKrishna Gudipati  */
1117a36c61f9SKrishna Gudipati void
bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s * fabric,struct bfa_fcs_vport_s * vport)1118a36c61f9SKrishna Gudipati bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
1119a36c61f9SKrishna Gudipati 			struct bfa_fcs_vport_s *vport)
1120a36c61f9SKrishna Gudipati {
11215fbe25c7SJing Huang 	/*
1122a36c61f9SKrishna Gudipati 	 * - add vport to fabric's vport_q
1123a36c61f9SKrishna Gudipati 	 */
1124a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric->vf_id);
1125a36c61f9SKrishna Gudipati 
1126a36c61f9SKrishna Gudipati 	list_add_tail(&vport->qe, &fabric->vport_q);
1127a36c61f9SKrishna Gudipati 	fabric->num_vports++;
1128a36c61f9SKrishna Gudipati 	bfa_wc_up(&fabric->wc);
1129a36c61f9SKrishna Gudipati }
1130a36c61f9SKrishna Gudipati 
11315fbe25c7SJing Huang /*
1132a36c61f9SKrishna Gudipati  *   A child vport is being deleted from fabric.
1133a36c61f9SKrishna Gudipati  *
1134a36c61f9SKrishna Gudipati  *   Vport is being deleted.
1135a36c61f9SKrishna Gudipati  */
1136a36c61f9SKrishna Gudipati void
bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s * fabric,struct bfa_fcs_vport_s * vport)1137a36c61f9SKrishna Gudipati bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
1138a36c61f9SKrishna Gudipati 			struct bfa_fcs_vport_s *vport)
1139a36c61f9SKrishna Gudipati {
1140a36c61f9SKrishna Gudipati 	list_del(&vport->qe);
1141a36c61f9SKrishna Gudipati 	fabric->num_vports--;
1142a36c61f9SKrishna Gudipati 	bfa_wc_down(&fabric->wc);
1143a36c61f9SKrishna Gudipati }
1144a36c61f9SKrishna Gudipati 
1145a36c61f9SKrishna Gudipati 
11465fbe25c7SJing Huang /*
114725985edcSLucas De Marchi  * Lookup for a vport within a fabric given its pwwn
1148a36c61f9SKrishna Gudipati  */
1149a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *
bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s * fabric,wwn_t pwwn)1150a36c61f9SKrishna Gudipati bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
1151a36c61f9SKrishna Gudipati {
1152a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1153a36c61f9SKrishna Gudipati 	struct list_head	      *qe;
1154a36c61f9SKrishna Gudipati 
1155a36c61f9SKrishna Gudipati 	list_for_each(qe, &fabric->vport_q) {
1156a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1157a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_get_pwwn(&vport->lport) == pwwn)
1158a36c61f9SKrishna Gudipati 			return vport;
1159a36c61f9SKrishna Gudipati 	}
1160a36c61f9SKrishna Gudipati 
1161a36c61f9SKrishna Gudipati 	return NULL;
1162a36c61f9SKrishna Gudipati }
1163a36c61f9SKrishna Gudipati 
1164a36c61f9SKrishna Gudipati 
1165a36c61f9SKrishna Gudipati /*
1166a36c61f9SKrishna Gudipati  *  Get OUI of the attached switch.
1167a36c61f9SKrishna Gudipati  *
1168a36c61f9SKrishna Gudipati  *  Note : Use of this function should be avoided as much as possible.
1169a36c61f9SKrishna Gudipati  *         This function should be used only if there is any requirement
1170a36c61f9SKrishna Gudipati *          to check for FOS version below 6.3.
1171a36c61f9SKrishna Gudipati  *         To check if the attached fabric is a brocade fabric, use
1172a36c61f9SKrishna Gudipati  *         bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
1173a36c61f9SKrishna Gudipati  *         or above only.
1174a36c61f9SKrishna Gudipati  */
1175a36c61f9SKrishna Gudipati 
1176a36c61f9SKrishna Gudipati u16
bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s * fabric)1177a36c61f9SKrishna Gudipati bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
1178a36c61f9SKrishna Gudipati {
1179a36c61f9SKrishna Gudipati 	wwn_t fab_nwwn;
1180a36c61f9SKrishna Gudipati 	u8 *tmp;
1181a36c61f9SKrishna Gudipati 	u16 oui;
1182a36c61f9SKrishna Gudipati 
1183f7f73812SMaggie Zhang 	fab_nwwn = fabric->lps->pr_nwwn;
1184a36c61f9SKrishna Gudipati 
1185a36c61f9SKrishna Gudipati 	tmp = (u8 *)&fab_nwwn;
1186a36c61f9SKrishna Gudipati 	oui = (tmp[3] << 8) | tmp[4];
1187a36c61f9SKrishna Gudipati 
1188a36c61f9SKrishna Gudipati 	return oui;
1189a36c61f9SKrishna Gudipati }
11905fbe25c7SJing Huang /*
1191a36c61f9SKrishna Gudipati  *		Unsolicited frame receive handling.
1192a36c61f9SKrishna Gudipati  */
1193a36c61f9SKrishna Gudipati void
bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s * fabric,struct fchs_s * fchs,u16 len)1194a36c61f9SKrishna Gudipati bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1195a36c61f9SKrishna Gudipati 		       u16 len)
1196a36c61f9SKrishna Gudipati {
1197a36c61f9SKrishna Gudipati 	u32	pid = fchs->d_id;
1198a36c61f9SKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1199a36c61f9SKrishna Gudipati 	struct list_head	      *qe;
1200a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1201a36c61f9SKrishna Gudipati 	struct fc_logi_s *flogi = (struct fc_logi_s *) els_cmd;
1202a36c61f9SKrishna Gudipati 
1203a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, len);
1204a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, pid);
1205a36c61f9SKrishna Gudipati 
12065fbe25c7SJing Huang 	/*
1207a36c61f9SKrishna Gudipati 	 * Look for our own FLOGI frames being looped back. This means an
1208a36c61f9SKrishna Gudipati 	 * external loopback cable is in place. Our own FLOGI frames are
1209a36c61f9SKrishna Gudipati 	 * sometimes looped back when switch port gets temporarily bypassed.
1210a36c61f9SKrishna Gudipati 	 */
1211f16a1750SMaggie Zhang 	if ((pid == bfa_ntoh3b(FC_FABRIC_PORT)) &&
1212a36c61f9SKrishna Gudipati 	    (els_cmd->els_code == FC_ELS_FLOGI) &&
1213a36c61f9SKrishna Gudipati 	    (flogi->port_name == bfa_fcs_lport_get_pwwn(&fabric->bport))) {
1214a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
1215a36c61f9SKrishna Gudipati 		return;
1216a36c61f9SKrishna Gudipati 	}
1217a36c61f9SKrishna Gudipati 
12185fbe25c7SJing Huang 	/*
1219a36c61f9SKrishna Gudipati 	 * FLOGI/EVFP exchanges should be consumed by base fabric.
1220a36c61f9SKrishna Gudipati 	 */
1221f16a1750SMaggie Zhang 	if (fchs->d_id == bfa_hton3b(FC_FABRIC_PORT)) {
1222a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, pid);
1223a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_process_uf(fabric, fchs, len);
1224a36c61f9SKrishna Gudipati 		return;
1225a36c61f9SKrishna Gudipati 	}
1226a36c61f9SKrishna Gudipati 
1227a36c61f9SKrishna Gudipati 	if (fabric->bport.pid == pid) {
12285fbe25c7SJing Huang 		/*
1229a36c61f9SKrishna Gudipati 		 * All authentication frames should be routed to auth
1230a36c61f9SKrishna Gudipati 		 */
1231a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, els_cmd->els_code);
1232a36c61f9SKrishna Gudipati 		if (els_cmd->els_code == FC_ELS_AUTH) {
1233a36c61f9SKrishna Gudipati 			bfa_trc(fabric->fcs, els_cmd->els_code);
1234a36c61f9SKrishna Gudipati 			return;
1235a36c61f9SKrishna Gudipati 		}
1236a36c61f9SKrishna Gudipati 
1237a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
1238a36c61f9SKrishna Gudipati 		bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
1239a36c61f9SKrishna Gudipati 		return;
1240a36c61f9SKrishna Gudipati 	}
1241a36c61f9SKrishna Gudipati 
12425fbe25c7SJing Huang 	/*
1243a36c61f9SKrishna Gudipati 	 * look for a matching local port ID
1244a36c61f9SKrishna Gudipati 	 */
1245a36c61f9SKrishna Gudipati 	list_for_each(qe, &fabric->vport_q) {
1246a36c61f9SKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1247a36c61f9SKrishna Gudipati 		if (vport->lport.pid == pid) {
1248a36c61f9SKrishna Gudipati 			bfa_fcs_lport_uf_recv(&vport->lport, fchs, len);
1249a36c61f9SKrishna Gudipati 			return;
1250a36c61f9SKrishna Gudipati 		}
1251a36c61f9SKrishna Gudipati 	}
125261ba4394SKrishna Gudipati 
125361ba4394SKrishna Gudipati 	if (!bfa_fcs_fabric_is_switched(fabric))
1254a36c61f9SKrishna Gudipati 		bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
125561ba4394SKrishna Gudipati 
125661ba4394SKrishna Gudipati 	bfa_trc(fabric->fcs, fchs->type);
1257a36c61f9SKrishna Gudipati }
1258a36c61f9SKrishna Gudipati 
12595fbe25c7SJing Huang /*
1260a36c61f9SKrishna Gudipati  *		Unsolicited frames to be processed by fabric.
1261a36c61f9SKrishna Gudipati  */
1262a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s * fabric,struct fchs_s * fchs,u16 len)1263a36c61f9SKrishna Gudipati bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1264a36c61f9SKrishna Gudipati 			  u16 len)
1265a36c61f9SKrishna Gudipati {
1266a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1267a36c61f9SKrishna Gudipati 
1268a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, els_cmd->els_code);
1269a36c61f9SKrishna Gudipati 
1270a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
1271a36c61f9SKrishna Gudipati 	case FC_ELS_FLOGI:
1272a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_process_flogi(fabric, fchs, len);
1273a36c61f9SKrishna Gudipati 		break;
1274a36c61f9SKrishna Gudipati 
1275a36c61f9SKrishna Gudipati 	default:
1276a36c61f9SKrishna Gudipati 		/*
1277a36c61f9SKrishna Gudipati 		 * need to generate a LS_RJT
1278a36c61f9SKrishna Gudipati 		 */
1279a36c61f9SKrishna Gudipati 		break;
1280a36c61f9SKrishna Gudipati 	}
1281a36c61f9SKrishna Gudipati }
1282a36c61f9SKrishna Gudipati 
12835fbe25c7SJing Huang /*
1284a36c61f9SKrishna Gudipati  *	Process	incoming FLOGI
1285a36c61f9SKrishna Gudipati  */
1286a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s * fabric,struct fchs_s * fchs,u16 len)1287a36c61f9SKrishna Gudipati bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
1288a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
1289a36c61f9SKrishna Gudipati {
1290a36c61f9SKrishna Gudipati 	struct fc_logi_s *flogi = (struct fc_logi_s *) (fchs + 1);
1291a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *bport = &fabric->bport;
1292a36c61f9SKrishna Gudipati 
1293a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fchs->s_id);
1294a36c61f9SKrishna Gudipati 
1295a36c61f9SKrishna Gudipati 	fabric->stats.flogi_rcvd++;
1296a36c61f9SKrishna Gudipati 	/*
1297a36c61f9SKrishna Gudipati 	 * Check port type. It should be 0 = n-port.
1298a36c61f9SKrishna Gudipati 	 */
1299a36c61f9SKrishna Gudipati 	if (flogi->csp.port_type) {
1300a36c61f9SKrishna Gudipati 		/*
1301a36c61f9SKrishna Gudipati 		 * @todo: may need to send a LS_RJT
1302a36c61f9SKrishna Gudipati 		 */
1303a36c61f9SKrishna Gudipati 		bfa_trc(fabric->fcs, flogi->port_name);
1304a36c61f9SKrishna Gudipati 		fabric->stats.flogi_rejected++;
1305a36c61f9SKrishna Gudipati 		return;
1306a36c61f9SKrishna Gudipati 	}
1307a36c61f9SKrishna Gudipati 
1308ba816ea8SJing Huang 	fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred);
1309a36c61f9SKrishna Gudipati 	bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
1310a36c61f9SKrishna Gudipati 	bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
1311a36c61f9SKrishna Gudipati 
1312a36c61f9SKrishna Gudipati 	/*
1313a36c61f9SKrishna Gudipati 	 * Send a Flogi Acc
1314a36c61f9SKrishna Gudipati 	 */
1315a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_send_flogi_acc(fabric);
1316a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
1317a36c61f9SKrishna Gudipati }
1318a36c61f9SKrishna Gudipati 
1319a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s * fabric)1320a36c61f9SKrishna Gudipati bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1321a36c61f9SKrishna Gudipati {
1322a36c61f9SKrishna Gudipati 	struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
1323a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
1324a36c61f9SKrishna Gudipati 	struct bfa_s	  *bfa = fabric->fcs->bfa;
1325a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1326a36c61f9SKrishna Gudipati 	u16	reqlen;
1327a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1328a36c61f9SKrishna Gudipati 
1329c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(fabric->fcs, BFA_FALSE);
13305fbe25c7SJing Huang 	/*
1331a36c61f9SKrishna Gudipati 	 * Do not expect this failure -- expect remote node to retry
1332a36c61f9SKrishna Gudipati 	 */
1333a36c61f9SKrishna Gudipati 	if (!fcxp)
1334a36c61f9SKrishna Gudipati 		return;
1335a36c61f9SKrishna Gudipati 
1336a36c61f9SKrishna Gudipati 	reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1337f16a1750SMaggie Zhang 				    bfa_hton3b(FC_FABRIC_PORT),
1338a36c61f9SKrishna Gudipati 				    n2n_port->reply_oxid, pcfg->pwwn,
1339a36c61f9SKrishna Gudipati 				    pcfg->nwwn,
1340a36c61f9SKrishna Gudipati 				    bfa_fcport_get_maxfrsize(bfa),
1341bbe37a67SVijaya Mohan Guvva 				    bfa_fcport_get_rx_bbcredit(bfa), 0);
1342a36c61f9SKrishna Gudipati 
13433fd45980SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->bfa_tag,
1344a36c61f9SKrishna Gudipati 		      BFA_FALSE, FC_CLASS_3,
1345a36c61f9SKrishna Gudipati 		      reqlen, &fchs, bfa_fcs_fabric_flogiacc_comp, fabric,
1346a36c61f9SKrishna Gudipati 		      FC_MAX_PDUSZ, 0);
1347a36c61f9SKrishna Gudipati }
1348a36c61f9SKrishna Gudipati 
13495fbe25c7SJing Huang /*
1350a36c61f9SKrishna Gudipati  *   Flogi Acc completion callback.
1351a36c61f9SKrishna Gudipati  */
1352a36c61f9SKrishna Gudipati static void
bfa_fcs_fabric_flogiacc_comp(void * fcsarg,struct bfa_fcxp_s * fcxp,void * cbarg,bfa_status_t status,u32 rsp_len,u32 resid_len,struct fchs_s * rspfchs)1353a36c61f9SKrishna Gudipati bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1354a36c61f9SKrishna Gudipati 			     bfa_status_t status, u32 rsp_len,
1355a36c61f9SKrishna Gudipati 			     u32 resid_len, struct fchs_s *rspfchs)
1356a36c61f9SKrishna Gudipati {
1357a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = cbarg;
1358a36c61f9SKrishna Gudipati 
1359a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, status);
1360a36c61f9SKrishna Gudipati }
1361a36c61f9SKrishna Gudipati 
13627826f304SKrishna Gudipati 
13637826f304SKrishna Gudipati /*
13647826f304SKrishna Gudipati  * Send AEN notification
13657826f304SKrishna Gudipati  */
13667826f304SKrishna Gudipati static void
bfa_fcs_fabric_aen_post(struct bfa_fcs_lport_s * port,enum bfa_port_aen_event event)13677826f304SKrishna Gudipati bfa_fcs_fabric_aen_post(struct bfa_fcs_lport_s *port,
13687826f304SKrishna Gudipati 			enum bfa_port_aen_event event)
13697826f304SKrishna Gudipati {
13707826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
13717826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
13727826f304SKrishna Gudipati 
13737826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
13747826f304SKrishna Gudipati 	if (!aen_entry)
13757826f304SKrishna Gudipati 		return;
13767826f304SKrishna Gudipati 
13777826f304SKrishna Gudipati 	aen_entry->aen_data.port.pwwn = bfa_fcs_lport_get_pwwn(port);
13787826f304SKrishna Gudipati 	aen_entry->aen_data.port.fwwn = bfa_fcs_lport_get_fabric_name(port);
13797826f304SKrishna Gudipati 
13807826f304SKrishna Gudipati 	/* Send the AEN notification */
13817826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
13827826f304SKrishna Gudipati 				  BFA_AEN_CAT_PORT, event);
13837826f304SKrishna Gudipati }
13847826f304SKrishna Gudipati 
1385a36c61f9SKrishna Gudipati /*
1386a36c61f9SKrishna Gudipati  *
1387a36c61f9SKrishna Gudipati  * @param[in] fabric - fabric
1388a36c61f9SKrishna Gudipati  * @param[in] wwn_t - new fabric name
1389a36c61f9SKrishna Gudipati  *
1390a36c61f9SKrishna Gudipati  * @return - none
1391a36c61f9SKrishna Gudipati  */
1392a36c61f9SKrishna Gudipati void
bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s * fabric,wwn_t fabric_name)1393a36c61f9SKrishna Gudipati bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1394a36c61f9SKrishna Gudipati 			       wwn_t fabric_name)
1395a36c61f9SKrishna Gudipati {
1396a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
1397a36c61f9SKrishna Gudipati 	char	pwwn_ptr[BFA_STRING_32];
1398a36c61f9SKrishna Gudipati 	char	fwwn_ptr[BFA_STRING_32];
1399a36c61f9SKrishna Gudipati 
1400a36c61f9SKrishna Gudipati 	bfa_trc(fabric->fcs, fabric_name);
1401a36c61f9SKrishna Gudipati 
1402a36c61f9SKrishna Gudipati 	if (fabric->fabric_name == 0) {
1403a36c61f9SKrishna Gudipati 		/*
1404a36c61f9SKrishna Gudipati 		 * With BRCD switches, we don't get Fabric Name in FLOGI.
1405a36c61f9SKrishna Gudipati 		 * Don't generate a fabric name change event in this case.
1406a36c61f9SKrishna Gudipati 		 */
1407a36c61f9SKrishna Gudipati 		fabric->fabric_name = fabric_name;
1408a36c61f9SKrishna Gudipati 	} else {
1409a36c61f9SKrishna Gudipati 		fabric->fabric_name = fabric_name;
1410a36c61f9SKrishna Gudipati 		wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport));
1411a36c61f9SKrishna Gudipati 		wwn2str(fwwn_ptr,
1412a36c61f9SKrishna Gudipati 			bfa_fcs_lport_get_fabric_name(&fabric->bport));
141388166242SJing Huang 		BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
1414a36c61f9SKrishna Gudipati 			"Base port WWN = %s Fabric WWN = %s\n",
1415a36c61f9SKrishna Gudipati 			pwwn_ptr, fwwn_ptr);
14167826f304SKrishna Gudipati 		bfa_fcs_fabric_aen_post(&fabric->bport,
14177826f304SKrishna Gudipati 				BFA_PORT_AEN_FABRIC_NAME_CHANGE);
1418a36c61f9SKrishna Gudipati 	}
1419a36c61f9SKrishna Gudipati }
1420a36c61f9SKrishna Gudipati 
1421881c1b3cSKrishna Gudipati void
bfa_cb_lps_flogo_comp(void * bfad,void * uarg)1422881c1b3cSKrishna Gudipati bfa_cb_lps_flogo_comp(void *bfad, void *uarg)
1423881c1b3cSKrishna Gudipati {
1424881c1b3cSKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = uarg;
1425881c1b3cSKrishna Gudipati 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOGOCOMP);
1426881c1b3cSKrishna Gudipati }
1427881c1b3cSKrishna Gudipati 
14285fbe25c7SJing Huang /*
1429a36c61f9SKrishna Gudipati  *	Returns FCS vf structure for a given vf_id.
1430a36c61f9SKrishna Gudipati  *
1431a36c61f9SKrishna Gudipati  *	param[in]	vf_id - VF_ID
1432a36c61f9SKrishna Gudipati  *
1433a36c61f9SKrishna Gudipati  *	return
1434a36c61f9SKrishna Gudipati  *	If lookup succeeds, retuns fcs vf object, otherwise returns NULL
1435a36c61f9SKrishna Gudipati  */
1436a36c61f9SKrishna Gudipati bfa_fcs_vf_t   *
bfa_fcs_vf_lookup(struct bfa_fcs_s * fcs,u16 vf_id)1437a36c61f9SKrishna Gudipati bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id)
1438a36c61f9SKrishna Gudipati {
1439a36c61f9SKrishna Gudipati 	bfa_trc(fcs, vf_id);
1440a36c61f9SKrishna Gudipati 	if (vf_id == FC_VF_ID_NULL)
1441a36c61f9SKrishna Gudipati 		return &fcs->fabric;
1442a36c61f9SKrishna Gudipati 
1443a36c61f9SKrishna Gudipati 	return NULL;
1444a36c61f9SKrishna Gudipati }
1445a36c61f9SKrishna Gudipati 
14465fbe25c7SJing Huang /*
1447b85daafeSKrishna Gudipati  *	Return the list of local logical ports present in the given VF.
1448b85daafeSKrishna Gudipati  *
1449b85daafeSKrishna Gudipati  *	@param[in]	vf	vf for which logical ports are returned
1450b85daafeSKrishna Gudipati  *	@param[out]	lpwwn	returned logical port wwn list
1451b85daafeSKrishna Gudipati  *	@param[in,out]	nlports in:size of lpwwn list;
1452b85daafeSKrishna Gudipati  *				out:total elements present,
1453b85daafeSKrishna Gudipati  *				actual elements returned is limited by the size
1454b85daafeSKrishna Gudipati  */
1455b85daafeSKrishna Gudipati void
bfa_fcs_vf_get_ports(bfa_fcs_vf_t * vf,wwn_t lpwwn[],int * nlports)1456b85daafeSKrishna Gudipati bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t lpwwn[], int *nlports)
1457b85daafeSKrishna Gudipati {
1458b85daafeSKrishna Gudipati 	struct list_head *qe;
1459b85daafeSKrishna Gudipati 	struct bfa_fcs_vport_s *vport;
1460b85daafeSKrishna Gudipati 	int	i = 0;
1461b85daafeSKrishna Gudipati 	struct bfa_fcs_s	*fcs;
1462b85daafeSKrishna Gudipati 
1463b85daafeSKrishna Gudipati 	if (vf == NULL || lpwwn == NULL || *nlports == 0)
1464b85daafeSKrishna Gudipati 		return;
1465b85daafeSKrishna Gudipati 
1466b85daafeSKrishna Gudipati 	fcs = vf->fcs;
1467b85daafeSKrishna Gudipati 
1468b85daafeSKrishna Gudipati 	bfa_trc(fcs, vf->vf_id);
1469b85daafeSKrishna Gudipati 	bfa_trc(fcs, (uint32_t) *nlports);
1470b85daafeSKrishna Gudipati 
1471b85daafeSKrishna Gudipati 	lpwwn[i++] = vf->bport.port_cfg.pwwn;
1472b85daafeSKrishna Gudipati 
1473b85daafeSKrishna Gudipati 	list_for_each(qe, &vf->vport_q) {
1474b85daafeSKrishna Gudipati 		if (i >= *nlports)
1475b85daafeSKrishna Gudipati 			break;
1476b85daafeSKrishna Gudipati 
1477b85daafeSKrishna Gudipati 		vport = (struct bfa_fcs_vport_s *) qe;
1478b85daafeSKrishna Gudipati 		lpwwn[i++] = vport->lport.port_cfg.pwwn;
1479b85daafeSKrishna Gudipati 	}
1480b85daafeSKrishna Gudipati 
1481b85daafeSKrishna Gudipati 	bfa_trc(fcs, i);
1482b85daafeSKrishna Gudipati 	*nlports = i;
1483b85daafeSKrishna Gudipati }
1484b85daafeSKrishna Gudipati 
1485b85daafeSKrishna Gudipati /*
1486a36c61f9SKrishna Gudipati  * BFA FCS PPORT ( physical port)
1487a36c61f9SKrishna Gudipati  */
1488a36c61f9SKrishna Gudipati static void
bfa_fcs_port_event_handler(void * cbarg,enum bfa_port_linkstate event)1489a36c61f9SKrishna Gudipati bfa_fcs_port_event_handler(void *cbarg, enum bfa_port_linkstate event)
1490a36c61f9SKrishna Gudipati {
1491a36c61f9SKrishna Gudipati 	struct bfa_fcs_s      *fcs = cbarg;
1492a36c61f9SKrishna Gudipati 
1493a36c61f9SKrishna Gudipati 	bfa_trc(fcs, event);
1494a36c61f9SKrishna Gudipati 
1495a36c61f9SKrishna Gudipati 	switch (event) {
1496a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKUP:
1497a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_link_up(&fcs->fabric);
1498a36c61f9SKrishna Gudipati 		break;
1499a36c61f9SKrishna Gudipati 
1500a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKDOWN:
1501a36c61f9SKrishna Gudipati 		bfa_fcs_fabric_link_down(&fcs->fabric);
1502a36c61f9SKrishna Gudipati 		break;
1503a36c61f9SKrishna Gudipati 
1504a36c61f9SKrishna Gudipati 	default:
1505d4b671c5SJing Huang 		WARN_ON(1);
1506a36c61f9SKrishna Gudipati 	}
1507a36c61f9SKrishna Gudipati }
1508a36c61f9SKrishna Gudipati 
15095fbe25c7SJing Huang /*
1510a36c61f9SKrishna Gudipati  * BFA FCS UF ( Unsolicited Frames)
1511a36c61f9SKrishna Gudipati  */
1512a36c61f9SKrishna Gudipati 
15135fbe25c7SJing Huang /*
1514a36c61f9SKrishna Gudipati  *		BFA callback for unsolicited frame receive handler.
1515a36c61f9SKrishna Gudipati  *
1516a36c61f9SKrishna Gudipati  * @param[in]		cbarg		callback arg for receive handler
1517a36c61f9SKrishna Gudipati  * @param[in]		uf		unsolicited frame descriptor
1518a36c61f9SKrishna Gudipati  *
1519a36c61f9SKrishna Gudipati  * @return None
1520a36c61f9SKrishna Gudipati  */
1521a36c61f9SKrishna Gudipati static void
bfa_fcs_uf_recv(void * cbarg,struct bfa_uf_s * uf)1522a36c61f9SKrishna Gudipati bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
1523a36c61f9SKrishna Gudipati {
1524a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs = (struct bfa_fcs_s *) cbarg;
1525a36c61f9SKrishna Gudipati 	struct fchs_s	*fchs = bfa_uf_get_frmbuf(uf);
1526a36c61f9SKrishna Gudipati 	u16	len = bfa_uf_get_frmlen(uf);
1527a36c61f9SKrishna Gudipati 	struct fc_vft_s *vft;
1528a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric;
1529a36c61f9SKrishna Gudipati 
15305fbe25c7SJing Huang 	/*
1531a36c61f9SKrishna Gudipati 	 * check for VFT header
1532a36c61f9SKrishna Gudipati 	 */
1533a36c61f9SKrishna Gudipati 	if (fchs->routing == FC_RTG_EXT_HDR &&
1534a36c61f9SKrishna Gudipati 	    fchs->cat_info == FC_CAT_VFT_HDR) {
1535a36c61f9SKrishna Gudipati 		bfa_stats(fcs, uf.tagged);
1536a36c61f9SKrishna Gudipati 		vft = bfa_uf_get_frmbuf(uf);
1537a36c61f9SKrishna Gudipati 		if (fcs->port_vfid == vft->vf_id)
1538a36c61f9SKrishna Gudipati 			fabric = &fcs->fabric;
1539a36c61f9SKrishna Gudipati 		else
1540a36c61f9SKrishna Gudipati 			fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id);
1541a36c61f9SKrishna Gudipati 
15425fbe25c7SJing Huang 		/*
1543a36c61f9SKrishna Gudipati 		 * drop frame if vfid is unknown
1544a36c61f9SKrishna Gudipati 		 */
1545a36c61f9SKrishna Gudipati 		if (!fabric) {
1546d4b671c5SJing Huang 			WARN_ON(1);
1547a36c61f9SKrishna Gudipati 			bfa_stats(fcs, uf.vfid_unknown);
1548a36c61f9SKrishna Gudipati 			bfa_uf_free(uf);
1549a36c61f9SKrishna Gudipati 			return;
1550a36c61f9SKrishna Gudipati 		}
1551a36c61f9SKrishna Gudipati 
15525fbe25c7SJing Huang 		/*
1553a36c61f9SKrishna Gudipati 		 * skip vft header
1554a36c61f9SKrishna Gudipati 		 */
1555a36c61f9SKrishna Gudipati 		fchs = (struct fchs_s *) (vft + 1);
1556a36c61f9SKrishna Gudipati 		len -= sizeof(struct fc_vft_s);
1557a36c61f9SKrishna Gudipati 
1558a36c61f9SKrishna Gudipati 		bfa_trc(fcs, vft->vf_id);
1559a36c61f9SKrishna Gudipati 	} else {
1560a36c61f9SKrishna Gudipati 		bfa_stats(fcs, uf.untagged);
1561a36c61f9SKrishna Gudipati 		fabric = &fcs->fabric;
1562a36c61f9SKrishna Gudipati 	}
1563a36c61f9SKrishna Gudipati 
1564a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[0]);
1565a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[1]);
1566a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[2]);
1567a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[3]);
1568a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[4]);
1569a36c61f9SKrishna Gudipati 	bfa_trc(fcs, ((u32 *) fchs)[5]);
1570a36c61f9SKrishna Gudipati 	bfa_trc(fcs, len);
1571a36c61f9SKrishna Gudipati 
1572a36c61f9SKrishna Gudipati 	bfa_fcs_fabric_uf_recv(fabric, fchs, len);
1573a36c61f9SKrishna Gudipati 	bfa_uf_free(uf);
1574a36c61f9SKrishna Gudipati }
1575a36c61f9SKrishna Gudipati 
1576984dc46cSChristoph Hellwig /*
1577984dc46cSChristoph Hellwig  * fcs attach -- called once to initialize data structures at driver attach time
1578984dc46cSChristoph Hellwig  */
1579a36c61f9SKrishna Gudipati void
bfa_fcs_attach(struct bfa_fcs_s * fcs,struct bfa_s * bfa,struct bfad_s * bfad,bfa_boolean_t min_cfg)1580984dc46cSChristoph Hellwig bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
1581984dc46cSChristoph Hellwig 	       bfa_boolean_t min_cfg)
1582a36c61f9SKrishna Gudipati {
1583984dc46cSChristoph Hellwig 	struct bfa_fcs_fabric_s *fabric = &fcs->fabric;
1584984dc46cSChristoph Hellwig 
1585984dc46cSChristoph Hellwig 	fcs->bfa = bfa;
1586984dc46cSChristoph Hellwig 	fcs->bfad = bfad;
1587984dc46cSChristoph Hellwig 	fcs->min_cfg = min_cfg;
1588984dc46cSChristoph Hellwig 	fcs->num_rport_logins = 0;
1589984dc46cSChristoph Hellwig 
1590984dc46cSChristoph Hellwig 	bfa->fcs = BFA_TRUE;
1591984dc46cSChristoph Hellwig 	fcbuild_init();
1592984dc46cSChristoph Hellwig 
1593984dc46cSChristoph Hellwig 	bfa_fcport_event_register(fcs->bfa, bfa_fcs_port_event_handler, fcs);
1594a36c61f9SKrishna Gudipati 	bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
1595984dc46cSChristoph Hellwig 
1596984dc46cSChristoph Hellwig 	memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
1597984dc46cSChristoph Hellwig 
1598984dc46cSChristoph Hellwig 	/*
1599984dc46cSChristoph Hellwig 	 * Initialize base fabric.
1600984dc46cSChristoph Hellwig 	 */
1601984dc46cSChristoph Hellwig 	fabric->fcs = fcs;
1602984dc46cSChristoph Hellwig 	INIT_LIST_HEAD(&fabric->vport_q);
1603984dc46cSChristoph Hellwig 	INIT_LIST_HEAD(&fabric->vf_q);
1604984dc46cSChristoph Hellwig 	fabric->lps = bfa_lps_alloc(fcs->bfa);
1605984dc46cSChristoph Hellwig 	WARN_ON(!fabric->lps);
1606984dc46cSChristoph Hellwig 
1607984dc46cSChristoph Hellwig 	/*
1608984dc46cSChristoph Hellwig 	 * Initialize fabric delete completion handler. Fabric deletion is
1609984dc46cSChristoph Hellwig 	 * complete when the last vport delete is complete.
1610984dc46cSChristoph Hellwig 	 */
1611984dc46cSChristoph Hellwig 	bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric);
1612984dc46cSChristoph Hellwig 	bfa_wc_up(&fabric->wc); /* For the base port */
1613984dc46cSChristoph Hellwig 
1614984dc46cSChristoph Hellwig 	bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
1615984dc46cSChristoph Hellwig 	bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
1616a36c61f9SKrishna Gudipati }
1617