1/* 2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. 3 * All rights reserved 4 * www.brocade.com 5 * 6 * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License (GPL) Version 2 as 10 * published by the Free Software Foundation 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 */ 17 18#include "bfad_drv.h" 19#include "bfa_ioc.h" 20#include "bfi_reg.h" 21#include "bfa_defs.h" 22 23BFA_TRC_FILE(CNA, IOC_CT); 24 25#define bfa_ioc_ct_sync_pos(__ioc) \ 26 ((uint32_t) (1 << bfa_ioc_pcifn(__ioc))) 27#define BFA_IOC_SYNC_REQD_SH 16 28#define bfa_ioc_ct_get_sync_ackd(__val) (__val & 0x0000ffff) 29#define bfa_ioc_ct_clear_sync_ackd(__val) (__val & 0xffff0000) 30#define bfa_ioc_ct_get_sync_reqd(__val) (__val >> BFA_IOC_SYNC_REQD_SH) 31#define bfa_ioc_ct_sync_reqd_pos(__ioc) \ 32 (bfa_ioc_ct_sync_pos(__ioc) << BFA_IOC_SYNC_REQD_SH) 33 34/* 35 * forward declarations 36 */ 37static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc); 38static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc); 39static void bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc); 40static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc); 41static bfa_boolean_t bfa_ioc_ct_sync_start(struct bfa_ioc_s *ioc); 42static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc); 43static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc); 44static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc); 45static bfa_boolean_t bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc); 46static void bfa_ioc_ct_set_cur_ioc_fwstate( 47 struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); 48static enum bfi_ioc_state bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc); 49static void bfa_ioc_ct_set_alt_ioc_fwstate( 50 struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); 51static enum bfi_ioc_state bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc); 52 53static struct bfa_ioc_hwif_s hwif_ct; 54static struct bfa_ioc_hwif_s hwif_ct2; 55 56/* 57 * Return true if firmware of current driver matches the running firmware. 58 */ 59static bfa_boolean_t 60bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) 61{ 62 enum bfi_ioc_state ioc_fwstate; 63 u32 usecnt; 64 struct bfi_ioc_image_hdr_s fwhdr; 65 66 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); 67 usecnt = readl(ioc->ioc_regs.ioc_usage_reg); 68 69 /* 70 * If usage count is 0, always return TRUE. 71 */ 72 if (usecnt == 0) { 73 writel(1, ioc->ioc_regs.ioc_usage_reg); 74 readl(ioc->ioc_regs.ioc_usage_sem_reg); 75 writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 76 writel(0, ioc->ioc_regs.ioc_fail_sync); 77 bfa_trc(ioc, usecnt); 78 return BFA_TRUE; 79 } 80 81 ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); 82 bfa_trc(ioc, ioc_fwstate); 83 84 /* 85 * Use count cannot be non-zero and chip in uninitialized state. 86 */ 87 WARN_ON(ioc_fwstate == BFI_IOC_UNINIT); 88 89 /* 90 * Check if another driver with a different firmware is active 91 */ 92 bfa_ioc_fwver_get(ioc, &fwhdr); 93 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { 94 readl(ioc->ioc_regs.ioc_usage_sem_reg); 95 writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 96 bfa_trc(ioc, usecnt); 97 return BFA_FALSE; 98 } 99 100 /* 101 * Same firmware version. Increment the reference count. 102 */ 103 usecnt++; 104 writel(usecnt, ioc->ioc_regs.ioc_usage_reg); 105 readl(ioc->ioc_regs.ioc_usage_sem_reg); 106 writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 107 bfa_trc(ioc, usecnt); 108 return BFA_TRUE; 109} 110 111static void 112bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) 113{ 114 u32 usecnt; 115 116 /* 117 * decrement usage count 118 */ 119 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); 120 usecnt = readl(ioc->ioc_regs.ioc_usage_reg); 121 WARN_ON(usecnt <= 0); 122 123 usecnt--; 124 writel(usecnt, ioc->ioc_regs.ioc_usage_reg); 125 bfa_trc(ioc, usecnt); 126 127 readl(ioc->ioc_regs.ioc_usage_sem_reg); 128 writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 129} 130 131/* 132 * Notify other functions on HB failure. 133 */ 134static void 135bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc) 136{ 137 if (bfa_ioc_is_cna(ioc)) { 138 writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt); 139 writel(__FW_INIT_HALT_P, ioc->ioc_regs.alt_ll_halt); 140 /* Wait for halt to take effect */ 141 readl(ioc->ioc_regs.ll_halt); 142 readl(ioc->ioc_regs.alt_ll_halt); 143 } else { 144 writel(~0U, ioc->ioc_regs.err_set); 145 readl(ioc->ioc_regs.err_set); 146 } 147} 148 149/* 150 * Host to LPU mailbox message addresses 151 */ 152static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } ct_fnreg[] = { 153 { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, 154 { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }, 155 { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 }, 156 { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 } 157}; 158 159/* 160 * Host <-> LPU mailbox command/status registers - port 0 161 */ 162static struct { u32 hfn, lpu; } ct_p0reg[] = { 163 { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT }, 164 { HOSTFN1_LPU0_CMD_STAT, LPU0_HOSTFN1_CMD_STAT }, 165 { HOSTFN2_LPU0_CMD_STAT, LPU0_HOSTFN2_CMD_STAT }, 166 { HOSTFN3_LPU0_CMD_STAT, LPU0_HOSTFN3_CMD_STAT } 167}; 168 169/* 170 * Host <-> LPU mailbox command/status registers - port 1 171 */ 172static struct { u32 hfn, lpu; } ct_p1reg[] = { 173 { HOSTFN0_LPU1_CMD_STAT, LPU1_HOSTFN0_CMD_STAT }, 174 { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT }, 175 { HOSTFN2_LPU1_CMD_STAT, LPU1_HOSTFN2_CMD_STAT }, 176 { HOSTFN3_LPU1_CMD_STAT, LPU1_HOSTFN3_CMD_STAT } 177}; 178 179static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn, hfn, lpu, lpu_read; } 180 ct2_reg[] = { 181 { CT2_HOSTFN_LPU0_MBOX0, CT2_LPU0_HOSTFN_MBOX0, CT2_HOSTFN_PAGE_NUM, 182 CT2_HOSTFN_LPU0_CMD_STAT, CT2_LPU0_HOSTFN_CMD_STAT, 183 CT2_HOSTFN_LPU0_READ_STAT}, 184 { CT2_HOSTFN_LPU1_MBOX0, CT2_LPU1_HOSTFN_MBOX0, CT2_HOSTFN_PAGE_NUM, 185 CT2_HOSTFN_LPU1_CMD_STAT, CT2_LPU1_HOSTFN_CMD_STAT, 186 CT2_HOSTFN_LPU1_READ_STAT}, 187}; 188 189static void 190bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc) 191{ 192 void __iomem *rb; 193 int pcifn = bfa_ioc_pcifn(ioc); 194 195 rb = bfa_ioc_bar0(ioc); 196 197 ioc->ioc_regs.hfn_mbox = rb + ct_fnreg[pcifn].hfn_mbox; 198 ioc->ioc_regs.lpu_mbox = rb + ct_fnreg[pcifn].lpu_mbox; 199 ioc->ioc_regs.host_page_num_fn = rb + ct_fnreg[pcifn].hfn_pgn; 200 201 if (ioc->port_id == 0) { 202 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; 203 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; 204 ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG; 205 ioc->ioc_regs.hfn_mbox_cmd = rb + ct_p0reg[pcifn].hfn; 206 ioc->ioc_regs.lpu_mbox_cmd = rb + ct_p0reg[pcifn].lpu; 207 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; 208 ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1; 209 } else { 210 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); 211 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); 212 ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC0_STATE_REG; 213 ioc->ioc_regs.hfn_mbox_cmd = rb + ct_p1reg[pcifn].hfn; 214 ioc->ioc_regs.lpu_mbox_cmd = rb + ct_p1reg[pcifn].lpu; 215 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; 216 ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0; 217 } 218 219 /* 220 * PSS control registers 221 */ 222 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); 223 ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); 224 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_LCLK_CTL_REG); 225 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_SCLK_CTL_REG); 226 227 /* 228 * IOC semaphore registers and serialization 229 */ 230 ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); 231 ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); 232 ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); 233 ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); 234 ioc->ioc_regs.ioc_fail_sync = (rb + BFA_IOC_FAIL_SYNC); 235 236 /* 237 * sram memory access 238 */ 239 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); 240 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; 241 242 /* 243 * err set reg : for notification of hb failure in fcmode 244 */ 245 ioc->ioc_regs.err_set = (rb + ERR_SET_REG); 246} 247 248static void 249bfa_ioc_ct2_reg_init(struct bfa_ioc_s *ioc) 250{ 251 void __iomem *rb; 252 int port = bfa_ioc_portid(ioc); 253 254 rb = bfa_ioc_bar0(ioc); 255 256 ioc->ioc_regs.hfn_mbox = rb + ct2_reg[port].hfn_mbox; 257 ioc->ioc_regs.lpu_mbox = rb + ct2_reg[port].lpu_mbox; 258 ioc->ioc_regs.host_page_num_fn = rb + ct2_reg[port].hfn_pgn; 259 ioc->ioc_regs.hfn_mbox_cmd = rb + ct2_reg[port].hfn; 260 ioc->ioc_regs.lpu_mbox_cmd = rb + ct2_reg[port].lpu; 261 ioc->ioc_regs.lpu_read_stat = rb + ct2_reg[port].lpu_read; 262 263 if (port == 0) { 264 ioc->ioc_regs.heartbeat = rb + CT2_BFA_IOC0_HBEAT_REG; 265 ioc->ioc_regs.ioc_fwstate = rb + CT2_BFA_IOC0_STATE_REG; 266 ioc->ioc_regs.alt_ioc_fwstate = rb + CT2_BFA_IOC1_STATE_REG; 267 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; 268 ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1; 269 } else { 270 ioc->ioc_regs.heartbeat = (rb + CT2_BFA_IOC1_HBEAT_REG); 271 ioc->ioc_regs.ioc_fwstate = (rb + CT2_BFA_IOC1_STATE_REG); 272 ioc->ioc_regs.alt_ioc_fwstate = rb + CT2_BFA_IOC0_STATE_REG; 273 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; 274 ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0; 275 } 276 277 /* 278 * PSS control registers 279 */ 280 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); 281 ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); 282 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + CT2_APP_PLL_LCLK_CTL_REG); 283 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + CT2_APP_PLL_SCLK_CTL_REG); 284 285 /* 286 * IOC semaphore registers and serialization 287 */ 288 ioc->ioc_regs.ioc_sem_reg = (rb + CT2_HOST_SEM0_REG); 289 ioc->ioc_regs.ioc_usage_sem_reg = (rb + CT2_HOST_SEM1_REG); 290 ioc->ioc_regs.ioc_init_sem_reg = (rb + CT2_HOST_SEM2_REG); 291 ioc->ioc_regs.ioc_usage_reg = (rb + CT2_BFA_FW_USE_COUNT); 292 ioc->ioc_regs.ioc_fail_sync = (rb + CT2_BFA_IOC_FAIL_SYNC); 293 294 /* 295 * sram memory access 296 */ 297 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); 298 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; 299 300 /* 301 * err set reg : for notification of hb failure in fcmode 302 */ 303 ioc->ioc_regs.err_set = (rb + ERR_SET_REG); 304} 305 306/* 307 * Initialize IOC to port mapping. 308 */ 309 310#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) 311static void 312bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc) 313{ 314 void __iomem *rb = ioc->pcidev.pci_bar_kva; 315 u32 r32; 316 317 /* 318 * For catapult, base port id on personality register and IOC type 319 */ 320 r32 = readl(rb + FNC_PERS_REG); 321 r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); 322 ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; 323 324 bfa_trc(ioc, bfa_ioc_pcifn(ioc)); 325 bfa_trc(ioc, ioc->port_id); 326} 327 328static void 329bfa_ioc_ct2_map_port(struct bfa_ioc_s *ioc) 330{ 331 void __iomem *rb = ioc->pcidev.pci_bar_kva; 332 u32 r32; 333 334 r32 = readl(rb + CT2_HOSTFN_PERSONALITY0); 335 ioc->port_id = ((r32 & __FC_LL_PORT_MAP__MK) >> __FC_LL_PORT_MAP__SH); 336 337 bfa_trc(ioc, bfa_ioc_pcifn(ioc)); 338 bfa_trc(ioc, ioc->port_id); 339} 340 341/* 342 * Set interrupt mode for a function: INTX or MSIX 343 */ 344static void 345bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) 346{ 347 void __iomem *rb = ioc->pcidev.pci_bar_kva; 348 u32 r32, mode; 349 350 r32 = readl(rb + FNC_PERS_REG); 351 bfa_trc(ioc, r32); 352 353 mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & 354 __F0_INTX_STATUS; 355 356 /* 357 * If already in desired mode, do not change anything 358 */ 359 if ((!msix && mode) || (msix && !mode)) 360 return; 361 362 if (msix) 363 mode = __F0_INTX_STATUS_MSIX; 364 else 365 mode = __F0_INTX_STATUS_INTA; 366 367 r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); 368 r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); 369 bfa_trc(ioc, r32); 370 371 writel(r32, rb + FNC_PERS_REG); 372} 373 374bfa_boolean_t 375bfa_ioc_ct2_lpu_read_stat(struct bfa_ioc_s *ioc) 376{ 377 u32 r32; 378 379 r32 = readl(ioc->ioc_regs.lpu_read_stat); 380 if (r32) { 381 writel(1, ioc->ioc_regs.lpu_read_stat); 382 return BFA_TRUE; 383 } 384 385 return BFA_FALSE; 386} 387 388/* 389 * Cleanup hw semaphore and usecnt registers 390 */ 391static void 392bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc) 393{ 394 395 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); 396 writel(0, ioc->ioc_regs.ioc_usage_reg); 397 readl(ioc->ioc_regs.ioc_usage_sem_reg); 398 writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 399 400 writel(0, ioc->ioc_regs.ioc_fail_sync); 401 /* 402 * Read the hw sem reg to make sure that it is locked 403 * before we clear it. If it is not locked, writing 1 404 * will lock it instead of clearing it. 405 */ 406 readl(ioc->ioc_regs.ioc_sem_reg); 407 writel(1, ioc->ioc_regs.ioc_sem_reg); 408} 409 410static bfa_boolean_t 411bfa_ioc_ct_sync_start(struct bfa_ioc_s *ioc) 412{ 413 uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); 414 uint32_t sync_reqd = bfa_ioc_ct_get_sync_reqd(r32); 415 416 /* 417 * Driver load time. If the sync required bit for this PCI fn 418 * is set, it is due to an unclean exit by the driver for this 419 * PCI fn in the previous incarnation. Whoever comes here first 420 * should clean it up, no matter which PCI fn. 421 */ 422 423 if (sync_reqd & bfa_ioc_ct_sync_pos(ioc)) { 424 writel(0, ioc->ioc_regs.ioc_fail_sync); 425 writel(1, ioc->ioc_regs.ioc_usage_reg); 426 writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate); 427 writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate); 428 return BFA_TRUE; 429 } 430 431 return bfa_ioc_ct_sync_complete(ioc); 432} 433 434/* 435 * Synchronized IOC failure processing routines 436 */ 437static void 438bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc) 439{ 440 uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); 441 uint32_t sync_pos = bfa_ioc_ct_sync_reqd_pos(ioc); 442 443 writel((r32 | sync_pos), ioc->ioc_regs.ioc_fail_sync); 444} 445 446static void 447bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc) 448{ 449 uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); 450 uint32_t sync_msk = bfa_ioc_ct_sync_reqd_pos(ioc) | 451 bfa_ioc_ct_sync_pos(ioc); 452 453 writel((r32 & ~sync_msk), ioc->ioc_regs.ioc_fail_sync); 454} 455 456static void 457bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc) 458{ 459 uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); 460 461 writel((r32 | bfa_ioc_ct_sync_pos(ioc)), 462 ioc->ioc_regs.ioc_fail_sync); 463} 464 465static bfa_boolean_t 466bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc) 467{ 468 uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); 469 uint32_t sync_reqd = bfa_ioc_ct_get_sync_reqd(r32); 470 uint32_t sync_ackd = bfa_ioc_ct_get_sync_ackd(r32); 471 uint32_t tmp_ackd; 472 473 if (sync_ackd == 0) 474 return BFA_TRUE; 475 476 /* 477 * The check below is to see whether any other PCI fn 478 * has reinitialized the ASIC (reset sync_ackd bits) 479 * and failed again while this IOC was waiting for hw 480 * semaphore (in bfa_iocpf_sm_semwait()). 481 */ 482 tmp_ackd = sync_ackd; 483 if ((sync_reqd & bfa_ioc_ct_sync_pos(ioc)) && 484 !(sync_ackd & bfa_ioc_ct_sync_pos(ioc))) 485 sync_ackd |= bfa_ioc_ct_sync_pos(ioc); 486 487 if (sync_reqd == sync_ackd) { 488 writel(bfa_ioc_ct_clear_sync_ackd(r32), 489 ioc->ioc_regs.ioc_fail_sync); 490 writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); 491 writel(BFI_IOC_FAIL, ioc->ioc_regs.alt_ioc_fwstate); 492 return BFA_TRUE; 493 } 494 495 /* 496 * If another PCI fn reinitialized and failed again while 497 * this IOC was waiting for hw sem, the sync_ackd bit for 498 * this IOC need to be set again to allow reinitialization. 499 */ 500 if (tmp_ackd != sync_ackd) 501 writel((r32 | sync_ackd), ioc->ioc_regs.ioc_fail_sync); 502 503 return BFA_FALSE; 504} 505 506/** 507 * Called from bfa_ioc_attach() to map asic specific calls. 508 */ 509static void 510bfa_ioc_set_ctx_hwif(struct bfa_ioc_s *ioc, struct bfa_ioc_hwif_s *hwif) 511{ 512 hwif->ioc_firmware_lock = bfa_ioc_ct_firmware_lock; 513 hwif->ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock; 514 hwif->ioc_notify_fail = bfa_ioc_ct_notify_fail; 515 hwif->ioc_ownership_reset = bfa_ioc_ct_ownership_reset; 516 hwif->ioc_sync_start = bfa_ioc_ct_sync_start; 517 hwif->ioc_sync_join = bfa_ioc_ct_sync_join; 518 hwif->ioc_sync_leave = bfa_ioc_ct_sync_leave; 519 hwif->ioc_sync_ack = bfa_ioc_ct_sync_ack; 520 hwif->ioc_sync_complete = bfa_ioc_ct_sync_complete; 521 hwif->ioc_set_fwstate = bfa_ioc_ct_set_cur_ioc_fwstate; 522 hwif->ioc_get_fwstate = bfa_ioc_ct_get_cur_ioc_fwstate; 523 hwif->ioc_set_alt_fwstate = bfa_ioc_ct_set_alt_ioc_fwstate; 524 hwif->ioc_get_alt_fwstate = bfa_ioc_ct_get_alt_ioc_fwstate; 525} 526 527/** 528 * Called from bfa_ioc_attach() to map asic specific calls. 529 */ 530void 531bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc) 532{ 533 bfa_ioc_set_ctx_hwif(ioc, &hwif_ct); 534 535 hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init; 536 hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init; 537 hwif_ct.ioc_map_port = bfa_ioc_ct_map_port; 538 hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; 539 ioc->ioc_hwif = &hwif_ct; 540} 541 542/** 543 * Called from bfa_ioc_attach() to map asic specific calls. 544 */ 545void 546bfa_ioc_set_ct2_hwif(struct bfa_ioc_s *ioc) 547{ 548 bfa_ioc_set_ctx_hwif(ioc, &hwif_ct2); 549 550 hwif_ct2.ioc_pll_init = bfa_ioc_ct2_pll_init; 551 hwif_ct2.ioc_reg_init = bfa_ioc_ct2_reg_init; 552 hwif_ct2.ioc_map_port = bfa_ioc_ct2_map_port; 553 hwif_ct2.ioc_lpu_read_stat = bfa_ioc_ct2_lpu_read_stat; 554 hwif_ct2.ioc_isr_mode_set = NULL; 555 ioc->ioc_hwif = &hwif_ct2; 556} 557 558/* 559 * Workaround for MSI-X resource allocation for catapult-2 with no asic block 560 */ 561#define HOSTFN_MSIX_DEFAULT 64 562#define HOSTFN_MSIX_VT_INDEX_MBOX_ERR 0x30138 563#define HOSTFN_MSIX_VT_OFST_NUMVT 0x3013c 564#define __MSIX_VT_NUMVT__MK 0x003ff800 565#define __MSIX_VT_NUMVT__SH 11 566#define __MSIX_VT_NUMVT_(_v) ((_v) << __MSIX_VT_NUMVT__SH) 567#define __MSIX_VT_OFST_ 0x000007ff 568void 569bfa_ioc_ct2_poweron(struct bfa_ioc_s *ioc) 570{ 571 void __iomem *rb = ioc->pcidev.pci_bar_kva; 572 u32 r32; 573 574 r32 = readl(rb + HOSTFN_MSIX_VT_OFST_NUMVT); 575 if (r32 & __MSIX_VT_NUMVT__MK) { 576 writel(r32 & __MSIX_VT_OFST_, 577 rb + HOSTFN_MSIX_VT_INDEX_MBOX_ERR); 578 return; 579 } 580 581 writel(__MSIX_VT_NUMVT_(HOSTFN_MSIX_DEFAULT - 1) | 582 HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc), 583 rb + HOSTFN_MSIX_VT_OFST_NUMVT); 584 writel(HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc), 585 rb + HOSTFN_MSIX_VT_INDEX_MBOX_ERR); 586} 587 588bfa_status_t 589bfa_ioc_ct_pll_init(void __iomem *rb, enum bfi_asic_mode mode) 590{ 591 u32 pll_sclk, pll_fclk, r32; 592 bfa_boolean_t fcmode = (mode == BFI_ASIC_MODE_FC); 593 594 pll_sclk = __APP_PLL_SCLK_LRESETN | __APP_PLL_SCLK_ENARST | 595 __APP_PLL_SCLK_RSEL200500 | __APP_PLL_SCLK_P0_1(3U) | 596 __APP_PLL_SCLK_JITLMT0_1(3U) | 597 __APP_PLL_SCLK_CNTLMT0_1(1U); 598 pll_fclk = __APP_PLL_LCLK_LRESETN | __APP_PLL_LCLK_ENARST | 599 __APP_PLL_LCLK_RSEL200500 | __APP_PLL_LCLK_P0_1(3U) | 600 __APP_PLL_LCLK_JITLMT0_1(3U) | 601 __APP_PLL_LCLK_CNTLMT0_1(1U); 602 603 if (fcmode) { 604 writel(0, (rb + OP_MODE)); 605 writel(__APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2 | 606 __APP_EMS_CHANNEL_SEL, (rb + ETH_MAC_SER_REG)); 607 } else { 608 writel(__GLOBAL_FCOE_MODE, (rb + OP_MODE)); 609 writel(__APP_EMS_REFCKBUFEN1, (rb + ETH_MAC_SER_REG)); 610 } 611 writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG)); 612 writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG)); 613 writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); 614 writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); 615 writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); 616 writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS)); 617 writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); 618 writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); 619 writel(pll_sclk | __APP_PLL_SCLK_LOGIC_SOFT_RESET, 620 rb + APP_PLL_SCLK_CTL_REG); 621 writel(pll_fclk | __APP_PLL_LCLK_LOGIC_SOFT_RESET, 622 rb + APP_PLL_LCLK_CTL_REG); 623 writel(pll_sclk | __APP_PLL_SCLK_LOGIC_SOFT_RESET | 624 __APP_PLL_SCLK_ENABLE, rb + APP_PLL_SCLK_CTL_REG); 625 writel(pll_fclk | __APP_PLL_LCLK_LOGIC_SOFT_RESET | 626 __APP_PLL_LCLK_ENABLE, rb + APP_PLL_LCLK_CTL_REG); 627 readl(rb + HOSTFN0_INT_MSK); 628 udelay(2000); 629 writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); 630 writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS)); 631 writel(pll_sclk | __APP_PLL_SCLK_ENABLE, rb + APP_PLL_SCLK_CTL_REG); 632 writel(pll_fclk | __APP_PLL_LCLK_ENABLE, rb + APP_PLL_LCLK_CTL_REG); 633 634 if (!fcmode) { 635 writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0)); 636 writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1)); 637 } 638 r32 = readl((rb + PSS_CTL_REG)); 639 r32 &= ~__PSS_LMEM_RESET; 640 writel(r32, (rb + PSS_CTL_REG)); 641 udelay(1000); 642 if (!fcmode) { 643 writel(0, (rb + PMM_1T_RESET_REG_P0)); 644 writel(0, (rb + PMM_1T_RESET_REG_P1)); 645 } 646 647 writel(__EDRAM_BISTR_START, (rb + MBIST_CTL_REG)); 648 udelay(1000); 649 r32 = readl((rb + MBIST_STAT_REG)); 650 writel(0, (rb + MBIST_CTL_REG)); 651 return BFA_STATUS_OK; 652} 653 654static void 655bfa_ioc_ct2_sclk_init(void __iomem *rb) 656{ 657 u32 r32; 658 659 /* 660 * put s_clk PLL and PLL FSM in reset 661 */ 662 r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); 663 r32 &= ~(__APP_PLL_SCLK_ENABLE | __APP_PLL_SCLK_LRESETN); 664 r32 |= (__APP_PLL_SCLK_ENARST | __APP_PLL_SCLK_BYPASS | 665 __APP_PLL_SCLK_LOGIC_SOFT_RESET); 666 writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG)); 667 668 /* 669 * Ignore mode and program for the max clock (which is FC16) 670 * Firmware/NFC will do the PLL init appropiately 671 */ 672 r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); 673 r32 &= ~(__APP_PLL_SCLK_REFCLK_SEL | __APP_PLL_SCLK_CLK_DIV2); 674 writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG)); 675 676 /* 677 * while doing PLL init dont clock gate ethernet subsystem 678 */ 679 r32 = readl((rb + CT2_CHIP_MISC_PRG)); 680 writel(r32 | __ETH_CLK_ENABLE_PORT0, (rb + CT2_CHIP_MISC_PRG)); 681 682 r32 = readl((rb + CT2_PCIE_MISC_REG)); 683 writel(r32 | __ETH_CLK_ENABLE_PORT1, (rb + CT2_PCIE_MISC_REG)); 684 685 /* 686 * set sclk value 687 */ 688 r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); 689 r32 &= (__P_SCLK_PLL_LOCK | __APP_PLL_SCLK_REFCLK_SEL | 690 __APP_PLL_SCLK_CLK_DIV2); 691 writel(r32 | 0x1061731b, (rb + CT2_APP_PLL_SCLK_CTL_REG)); 692 693 /* 694 * poll for s_clk lock or delay 1ms 695 */ 696 udelay(1000); 697} 698 699static void 700bfa_ioc_ct2_lclk_init(void __iomem *rb) 701{ 702 u32 r32; 703 704 /* 705 * put l_clk PLL and PLL FSM in reset 706 */ 707 r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); 708 r32 &= ~(__APP_PLL_LCLK_ENABLE | __APP_PLL_LCLK_LRESETN); 709 r32 |= (__APP_PLL_LCLK_ENARST | __APP_PLL_LCLK_BYPASS | 710 __APP_PLL_LCLK_LOGIC_SOFT_RESET); 711 writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); 712 713 /* 714 * set LPU speed (set for FC16 which will work for other modes) 715 */ 716 r32 = readl((rb + CT2_CHIP_MISC_PRG)); 717 writel(r32, (rb + CT2_CHIP_MISC_PRG)); 718 719 /* 720 * set LPU half speed (set for FC16 which will work for other modes) 721 */ 722 r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); 723 writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); 724 725 /* 726 * set lclk for mode (set for FC16) 727 */ 728 r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); 729 r32 &= (__P_LCLK_PLL_LOCK | __APP_LPUCLK_HALFSPEED); 730 r32 |= 0x20c1731b; 731 writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); 732 733 /* 734 * poll for s_clk lock or delay 1ms 735 */ 736 udelay(1000); 737} 738 739static void 740bfa_ioc_ct2_mem_init(void __iomem *rb) 741{ 742 u32 r32; 743 744 r32 = readl((rb + PSS_CTL_REG)); 745 r32 &= ~__PSS_LMEM_RESET; 746 writel(r32, (rb + PSS_CTL_REG)); 747 udelay(1000); 748 749 writel(__EDRAM_BISTR_START, (rb + CT2_MBIST_CTL_REG)); 750 udelay(1000); 751 writel(0, (rb + CT2_MBIST_CTL_REG)); 752} 753 754void 755bfa_ioc_ct2_mac_reset(void __iomem *rb) 756{ 757 /* put port0, port1 MAC & AHB in reset */ 758 writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET), 759 rb + CT2_CSI_MAC_CONTROL_REG(0)); 760 writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET), 761 rb + CT2_CSI_MAC_CONTROL_REG(1)); 762} 763 764static void 765bfa_ioc_ct2_enable_flash(void __iomem *rb) 766{ 767 u32 r32; 768 769 r32 = readl((rb + PSS_GPIO_OUT_REG)); 770 writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG)); 771 r32 = readl((rb + PSS_GPIO_OE_REG)); 772 writel(r32 | 1, (rb + PSS_GPIO_OE_REG)); 773} 774 775#define CT2_NFC_MAX_DELAY 1000 776#define CT2_NFC_PAUSE_MAX_DELAY 4000 777#define CT2_NFC_VER_VALID 0x147 778#define CT2_NFC_STATE_RUNNING 0x20000001 779#define BFA_IOC_PLL_POLL 1000000 780 781static bfa_boolean_t 782bfa_ioc_ct2_nfc_halted(void __iomem *rb) 783{ 784 u32 r32; 785 786 r32 = readl(rb + CT2_NFC_CSR_SET_REG); 787 if (r32 & __NFC_CONTROLLER_HALTED) 788 return BFA_TRUE; 789 790 return BFA_FALSE; 791} 792 793static void 794bfa_ioc_ct2_nfc_halt(void __iomem *rb) 795{ 796 int i; 797 798 writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG); 799 for (i = 0; i < CT2_NFC_MAX_DELAY; i++) { 800 if (bfa_ioc_ct2_nfc_halted(rb)) 801 break; 802 udelay(1000); 803 } 804 WARN_ON(!bfa_ioc_ct2_nfc_halted(rb)); 805} 806 807static void 808bfa_ioc_ct2_nfc_resume(void __iomem *rb) 809{ 810 u32 r32; 811 int i; 812 813 writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_CLR_REG); 814 for (i = 0; i < CT2_NFC_MAX_DELAY; i++) { 815 r32 = readl(rb + CT2_NFC_CSR_SET_REG); 816 if (!(r32 & __NFC_CONTROLLER_HALTED)) 817 return; 818 udelay(1000); 819 } 820 WARN_ON(1); 821} 822 823static void 824bfa_ioc_ct2_clk_reset(void __iomem *rb) 825{ 826 u32 r32; 827 828 bfa_ioc_ct2_sclk_init(rb); 829 bfa_ioc_ct2_lclk_init(rb); 830 831 /* 832 * release soft reset on s_clk & l_clk 833 */ 834 r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); 835 writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET, 836 (rb + CT2_APP_PLL_SCLK_CTL_REG)); 837 838 r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); 839 writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET, 840 (rb + CT2_APP_PLL_LCLK_CTL_REG)); 841 842} 843 844static void 845bfa_ioc_ct2_nfc_clk_reset(void __iomem *rb) 846{ 847 u32 r32, i; 848 849 r32 = readl((rb + PSS_CTL_REG)); 850 r32 |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET); 851 writel(r32, (rb + PSS_CTL_REG)); 852 853 writel(__RESET_AND_START_SCLK_LCLK_PLLS, rb + CT2_CSI_FW_CTL_SET_REG); 854 855 for (i = 0; i < BFA_IOC_PLL_POLL; i++) { 856 r32 = readl(rb + CT2_NFC_FLASH_STS_REG); 857 858 if ((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)) 859 break; 860 } 861 WARN_ON(!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)); 862 863 for (i = 0; i < BFA_IOC_PLL_POLL; i++) { 864 r32 = readl(rb + CT2_NFC_FLASH_STS_REG); 865 866 if (!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)) 867 break; 868 } 869 WARN_ON((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)); 870 871 r32 = readl(rb + CT2_CSI_FW_CTL_REG); 872 WARN_ON((r32 & __RESET_AND_START_SCLK_LCLK_PLLS)); 873} 874 875static void 876bfa_ioc_ct2_wait_till_nfc_running(void __iomem *rb) 877{ 878 u32 r32; 879 int i; 880 881 if (bfa_ioc_ct2_nfc_halted(rb)) 882 bfa_ioc_ct2_nfc_resume(rb); 883 for (i = 0; i < CT2_NFC_PAUSE_MAX_DELAY; i++) { 884 r32 = readl(rb + CT2_NFC_STS_REG); 885 if (r32 == CT2_NFC_STATE_RUNNING) 886 return; 887 udelay(1000); 888 } 889 890 r32 = readl(rb + CT2_NFC_STS_REG); 891 WARN_ON(!(r32 == CT2_NFC_STATE_RUNNING)); 892} 893 894bfa_status_t 895bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) 896{ 897 u32 wgn, r32, nfc_ver; 898 899 wgn = readl(rb + CT2_WGN_STATUS); 900 901 if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) { 902 /* 903 * If flash is corrupted, enable flash explicitly 904 */ 905 bfa_ioc_ct2_clk_reset(rb); 906 bfa_ioc_ct2_enable_flash(rb); 907 908 bfa_ioc_ct2_mac_reset(rb); 909 910 bfa_ioc_ct2_clk_reset(rb); 911 bfa_ioc_ct2_enable_flash(rb); 912 913 } else { 914 nfc_ver = readl(rb + CT2_RSC_GPR15_REG); 915 916 if ((nfc_ver >= CT2_NFC_VER_VALID) && 917 (wgn == (__A2T_AHB_LOAD | __WGN_READY))) { 918 919 bfa_ioc_ct2_wait_till_nfc_running(rb); 920 921 bfa_ioc_ct2_nfc_clk_reset(rb); 922 } else { 923 bfa_ioc_ct2_nfc_halt(rb); 924 925 bfa_ioc_ct2_clk_reset(rb); 926 bfa_ioc_ct2_mac_reset(rb); 927 bfa_ioc_ct2_clk_reset(rb); 928 929 } 930 } 931 /* 932 * The very first PCIe DMA Read done by LPU fails with a fatal error, 933 * when Address Translation Cache (ATC) has been enabled by system BIOS. 934 * 935 * Workaround: 936 * Disable Invalidated Tag Match Enable capability by setting the bit 26 937 * of CHIP_MISC_PRG to 0, by default it is set to 1. 938 */ 939 r32 = readl(rb + CT2_CHIP_MISC_PRG); 940 writel((r32 & 0xfbffffff), (rb + CT2_CHIP_MISC_PRG)); 941 942 /* 943 * Mask the interrupts and clear any 944 * pending interrupts left by BIOS/EFI 945 */ 946 947 writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK)); 948 writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK)); 949 950 /* For first time initialization, no need to clear interrupts */ 951 r32 = readl(rb + HOST_SEM5_REG); 952 if (r32 & 0x1) { 953 r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); 954 if (r32 == 1) { 955 writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT)); 956 readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); 957 } 958 r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT)); 959 if (r32 == 1) { 960 writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT)); 961 readl((rb + CT2_LPU1_HOSTFN_CMD_STAT)); 962 } 963 } 964 965 bfa_ioc_ct2_mem_init(rb); 966 967 writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG)); 968 writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG)); 969 970 return BFA_STATUS_OK; 971} 972 973static void 974bfa_ioc_ct_set_cur_ioc_fwstate(struct bfa_ioc_s *ioc, 975 enum bfi_ioc_state fwstate) 976{ 977 writel(fwstate, ioc->ioc_regs.ioc_fwstate); 978} 979 980static enum bfi_ioc_state 981bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc) 982{ 983 return (enum bfi_ioc_state)readl(ioc->ioc_regs.ioc_fwstate); 984} 985 986static void 987bfa_ioc_ct_set_alt_ioc_fwstate(struct bfa_ioc_s *ioc, 988 enum bfi_ioc_state fwstate) 989{ 990 writel(fwstate, ioc->ioc_regs.alt_ioc_fwstate); 991} 992 993static enum bfi_ioc_state 994bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc) 995{ 996 return (enum bfi_ioc_state) readl(ioc->ioc_regs.alt_ioc_fwstate); 997} 998