1*52fa7bf9SThomas 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 7648c5a50e8SArnd Bergmann strlcpy(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 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 */ 8258c5a50e8SArnd Bergmann strlcpy(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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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