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