0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "bfad_drv.h"
0012 #include "bfa_ioc.h"
0013 #include "bfi_reg.h"
0014 #include "bfa_defs.h"
0015
0016 BFA_TRC_FILE(CNA, IOC_CT);
0017
0018 #define bfa_ioc_ct_sync_pos(__ioc) \
0019 ((uint32_t) (1 << bfa_ioc_pcifn(__ioc)))
0020 #define BFA_IOC_SYNC_REQD_SH 16
0021 #define bfa_ioc_ct_get_sync_ackd(__val) (__val & 0x0000ffff)
0022 #define bfa_ioc_ct_clear_sync_ackd(__val) (__val & 0xffff0000)
0023 #define bfa_ioc_ct_get_sync_reqd(__val) (__val >> BFA_IOC_SYNC_REQD_SH)
0024 #define bfa_ioc_ct_sync_reqd_pos(__ioc) \
0025 (bfa_ioc_ct_sync_pos(__ioc) << BFA_IOC_SYNC_REQD_SH)
0026
0027
0028
0029
0030 static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
0031 static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
0032 static void bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc);
0033 static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
0034 static bfa_boolean_t bfa_ioc_ct_sync_start(struct bfa_ioc_s *ioc);
0035 static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc);
0036 static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc);
0037 static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc);
0038 static bfa_boolean_t bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc);
0039 static void bfa_ioc_ct_set_cur_ioc_fwstate(
0040 struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate);
0041 static enum bfi_ioc_state bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc);
0042 static void bfa_ioc_ct_set_alt_ioc_fwstate(
0043 struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate);
0044 static enum bfi_ioc_state bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc);
0045
0046 static struct bfa_ioc_hwif_s hwif_ct;
0047 static struct bfa_ioc_hwif_s hwif_ct2;
0048
0049
0050
0051
0052 static bfa_boolean_t
0053 bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
0054 {
0055 enum bfi_ioc_state ioc_fwstate;
0056 u32 usecnt;
0057 struct bfi_ioc_image_hdr_s fwhdr;
0058
0059 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
0060 usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
0061
0062
0063
0064
0065 if (usecnt == 0) {
0066 writel(1, ioc->ioc_regs.ioc_usage_reg);
0067 readl(ioc->ioc_regs.ioc_usage_sem_reg);
0068 writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
0069 writel(0, ioc->ioc_regs.ioc_fail_sync);
0070 bfa_trc(ioc, usecnt);
0071 return BFA_TRUE;
0072 }
0073
0074 ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
0075 bfa_trc(ioc, ioc_fwstate);
0076
0077
0078
0079
0080 WARN_ON(ioc_fwstate == BFI_IOC_UNINIT);
0081
0082
0083
0084
0085 bfa_ioc_fwver_get(ioc, &fwhdr);
0086 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
0087 readl(ioc->ioc_regs.ioc_usage_sem_reg);
0088 writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
0089 bfa_trc(ioc, usecnt);
0090 return BFA_FALSE;
0091 }
0092
0093
0094
0095
0096 usecnt++;
0097 writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
0098 readl(ioc->ioc_regs.ioc_usage_sem_reg);
0099 writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
0100 bfa_trc(ioc, usecnt);
0101 return BFA_TRUE;
0102 }
0103
0104 static void
0105 bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
0106 {
0107 u32 usecnt;
0108
0109
0110
0111
0112 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
0113 usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
0114 WARN_ON(usecnt <= 0);
0115
0116 usecnt--;
0117 writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
0118 bfa_trc(ioc, usecnt);
0119
0120 readl(ioc->ioc_regs.ioc_usage_sem_reg);
0121 writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
0122 }
0123
0124
0125
0126
0127 static void
0128 bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc)
0129 {
0130 if (bfa_ioc_is_cna(ioc)) {
0131 writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
0132 writel(__FW_INIT_HALT_P, ioc->ioc_regs.alt_ll_halt);
0133
0134 readl(ioc->ioc_regs.ll_halt);
0135 readl(ioc->ioc_regs.alt_ll_halt);
0136 } else {
0137 writel(~0U, ioc->ioc_regs.err_set);
0138 readl(ioc->ioc_regs.err_set);
0139 }
0140 }
0141
0142
0143
0144
0145 static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } ct_fnreg[] = {
0146 { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
0147 { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
0148 { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
0149 { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
0150 };
0151
0152
0153
0154
0155 static struct { u32 hfn, lpu; } ct_p0reg[] = {
0156 { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
0157 { HOSTFN1_LPU0_CMD_STAT, LPU0_HOSTFN1_CMD_STAT },
0158 { HOSTFN2_LPU0_CMD_STAT, LPU0_HOSTFN2_CMD_STAT },
0159 { HOSTFN3_LPU0_CMD_STAT, LPU0_HOSTFN3_CMD_STAT }
0160 };
0161
0162
0163
0164
0165 static struct { u32 hfn, lpu; } ct_p1reg[] = {
0166 { HOSTFN0_LPU1_CMD_STAT, LPU1_HOSTFN0_CMD_STAT },
0167 { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT },
0168 { HOSTFN2_LPU1_CMD_STAT, LPU1_HOSTFN2_CMD_STAT },
0169 { HOSTFN3_LPU1_CMD_STAT, LPU1_HOSTFN3_CMD_STAT }
0170 };
0171
0172 static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn, hfn, lpu, lpu_read; }
0173 ct2_reg[] = {
0174 { CT2_HOSTFN_LPU0_MBOX0, CT2_LPU0_HOSTFN_MBOX0, CT2_HOSTFN_PAGE_NUM,
0175 CT2_HOSTFN_LPU0_CMD_STAT, CT2_LPU0_HOSTFN_CMD_STAT,
0176 CT2_HOSTFN_LPU0_READ_STAT},
0177 { CT2_HOSTFN_LPU1_MBOX0, CT2_LPU1_HOSTFN_MBOX0, CT2_HOSTFN_PAGE_NUM,
0178 CT2_HOSTFN_LPU1_CMD_STAT, CT2_LPU1_HOSTFN_CMD_STAT,
0179 CT2_HOSTFN_LPU1_READ_STAT},
0180 };
0181
0182 static void
0183 bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
0184 {
0185 void __iomem *rb;
0186 int pcifn = bfa_ioc_pcifn(ioc);
0187
0188 rb = bfa_ioc_bar0(ioc);
0189
0190 ioc->ioc_regs.hfn_mbox = rb + ct_fnreg[pcifn].hfn_mbox;
0191 ioc->ioc_regs.lpu_mbox = rb + ct_fnreg[pcifn].lpu_mbox;
0192 ioc->ioc_regs.host_page_num_fn = rb + ct_fnreg[pcifn].hfn_pgn;
0193
0194 if (ioc->port_id == 0) {
0195 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
0196 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
0197 ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG;
0198 ioc->ioc_regs.hfn_mbox_cmd = rb + ct_p0reg[pcifn].hfn;
0199 ioc->ioc_regs.lpu_mbox_cmd = rb + ct_p0reg[pcifn].lpu;
0200 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
0201 ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1;
0202 } else {
0203 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
0204 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
0205 ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC0_STATE_REG;
0206 ioc->ioc_regs.hfn_mbox_cmd = rb + ct_p1reg[pcifn].hfn;
0207 ioc->ioc_regs.lpu_mbox_cmd = rb + ct_p1reg[pcifn].lpu;
0208 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
0209 ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0;
0210 }
0211
0212
0213
0214
0215 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
0216 ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
0217 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_LCLK_CTL_REG);
0218 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_SCLK_CTL_REG);
0219
0220
0221
0222
0223 ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
0224 ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
0225 ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
0226 ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
0227 ioc->ioc_regs.ioc_fail_sync = (rb + BFA_IOC_FAIL_SYNC);
0228
0229
0230
0231
0232 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
0233 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
0234
0235
0236
0237
0238 ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
0239 }
0240
0241 static void
0242 bfa_ioc_ct2_reg_init(struct bfa_ioc_s *ioc)
0243 {
0244 void __iomem *rb;
0245 int port = bfa_ioc_portid(ioc);
0246
0247 rb = bfa_ioc_bar0(ioc);
0248
0249 ioc->ioc_regs.hfn_mbox = rb + ct2_reg[port].hfn_mbox;
0250 ioc->ioc_regs.lpu_mbox = rb + ct2_reg[port].lpu_mbox;
0251 ioc->ioc_regs.host_page_num_fn = rb + ct2_reg[port].hfn_pgn;
0252 ioc->ioc_regs.hfn_mbox_cmd = rb + ct2_reg[port].hfn;
0253 ioc->ioc_regs.lpu_mbox_cmd = rb + ct2_reg[port].lpu;
0254 ioc->ioc_regs.lpu_read_stat = rb + ct2_reg[port].lpu_read;
0255
0256 if (port == 0) {
0257 ioc->ioc_regs.heartbeat = rb + CT2_BFA_IOC0_HBEAT_REG;
0258 ioc->ioc_regs.ioc_fwstate = rb + CT2_BFA_IOC0_STATE_REG;
0259 ioc->ioc_regs.alt_ioc_fwstate = rb + CT2_BFA_IOC1_STATE_REG;
0260 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
0261 ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1;
0262 } else {
0263 ioc->ioc_regs.heartbeat = (rb + CT2_BFA_IOC1_HBEAT_REG);
0264 ioc->ioc_regs.ioc_fwstate = (rb + CT2_BFA_IOC1_STATE_REG);
0265 ioc->ioc_regs.alt_ioc_fwstate = rb + CT2_BFA_IOC0_STATE_REG;
0266 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
0267 ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0;
0268 }
0269
0270
0271
0272
0273 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
0274 ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
0275 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + CT2_APP_PLL_LCLK_CTL_REG);
0276 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + CT2_APP_PLL_SCLK_CTL_REG);
0277
0278
0279
0280
0281 ioc->ioc_regs.ioc_sem_reg = (rb + CT2_HOST_SEM0_REG);
0282 ioc->ioc_regs.ioc_usage_sem_reg = (rb + CT2_HOST_SEM1_REG);
0283 ioc->ioc_regs.ioc_init_sem_reg = (rb + CT2_HOST_SEM2_REG);
0284 ioc->ioc_regs.ioc_usage_reg = (rb + CT2_BFA_FW_USE_COUNT);
0285 ioc->ioc_regs.ioc_fail_sync = (rb + CT2_BFA_IOC_FAIL_SYNC);
0286
0287
0288
0289
0290 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
0291 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
0292
0293
0294
0295
0296 ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
0297 }
0298
0299
0300
0301
0302
0303 #define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
0304 static void
0305 bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
0306 {
0307 void __iomem *rb = ioc->pcidev.pci_bar_kva;
0308 u32 r32;
0309
0310
0311
0312
0313 r32 = readl(rb + FNC_PERS_REG);
0314 r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
0315 ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
0316
0317 bfa_trc(ioc, bfa_ioc_pcifn(ioc));
0318 bfa_trc(ioc, ioc->port_id);
0319 }
0320
0321 static void
0322 bfa_ioc_ct2_map_port(struct bfa_ioc_s *ioc)
0323 {
0324 void __iomem *rb = ioc->pcidev.pci_bar_kva;
0325 u32 r32;
0326
0327 r32 = readl(rb + CT2_HOSTFN_PERSONALITY0);
0328 ioc->port_id = ((r32 & __FC_LL_PORT_MAP__MK) >> __FC_LL_PORT_MAP__SH);
0329
0330 bfa_trc(ioc, bfa_ioc_pcifn(ioc));
0331 bfa_trc(ioc, ioc->port_id);
0332 }
0333
0334
0335
0336
0337 static void
0338 bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
0339 {
0340 void __iomem *rb = ioc->pcidev.pci_bar_kva;
0341 u32 r32, mode;
0342
0343 r32 = readl(rb + FNC_PERS_REG);
0344 bfa_trc(ioc, r32);
0345
0346 mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
0347 __F0_INTX_STATUS;
0348
0349
0350
0351
0352 if ((!msix && mode) || (msix && !mode))
0353 return;
0354
0355 if (msix)
0356 mode = __F0_INTX_STATUS_MSIX;
0357 else
0358 mode = __F0_INTX_STATUS_INTA;
0359
0360 r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
0361 r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
0362 bfa_trc(ioc, r32);
0363
0364 writel(r32, rb + FNC_PERS_REG);
0365 }
0366
0367 static bfa_boolean_t
0368 bfa_ioc_ct2_lpu_read_stat(struct bfa_ioc_s *ioc)
0369 {
0370 u32 r32;
0371
0372 r32 = readl(ioc->ioc_regs.lpu_read_stat);
0373 if (r32) {
0374 writel(1, ioc->ioc_regs.lpu_read_stat);
0375 return BFA_TRUE;
0376 }
0377
0378 return BFA_FALSE;
0379 }
0380
0381
0382
0383
0384 static void
0385 bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
0386 {
0387
0388 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
0389 writel(0, ioc->ioc_regs.ioc_usage_reg);
0390 readl(ioc->ioc_regs.ioc_usage_sem_reg);
0391 writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
0392
0393 writel(0, ioc->ioc_regs.ioc_fail_sync);
0394
0395
0396
0397
0398
0399 readl(ioc->ioc_regs.ioc_sem_reg);
0400 writel(1, ioc->ioc_regs.ioc_sem_reg);
0401 }
0402
0403 static bfa_boolean_t
0404 bfa_ioc_ct_sync_start(struct bfa_ioc_s *ioc)
0405 {
0406 uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
0407 uint32_t sync_reqd = bfa_ioc_ct_get_sync_reqd(r32);
0408
0409
0410
0411
0412
0413
0414
0415
0416 if (sync_reqd & bfa_ioc_ct_sync_pos(ioc)) {
0417 writel(0, ioc->ioc_regs.ioc_fail_sync);
0418 writel(1, ioc->ioc_regs.ioc_usage_reg);
0419 writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
0420 writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate);
0421 return BFA_TRUE;
0422 }
0423
0424 return bfa_ioc_ct_sync_complete(ioc);
0425 }
0426
0427
0428
0429
0430 static void
0431 bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc)
0432 {
0433 uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
0434 uint32_t sync_pos = bfa_ioc_ct_sync_reqd_pos(ioc);
0435
0436 writel((r32 | sync_pos), ioc->ioc_regs.ioc_fail_sync);
0437 }
0438
0439 static void
0440 bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc)
0441 {
0442 uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
0443 uint32_t sync_msk = bfa_ioc_ct_sync_reqd_pos(ioc) |
0444 bfa_ioc_ct_sync_pos(ioc);
0445
0446 writel((r32 & ~sync_msk), ioc->ioc_regs.ioc_fail_sync);
0447 }
0448
0449 static void
0450 bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc)
0451 {
0452 uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
0453
0454 writel((r32 | bfa_ioc_ct_sync_pos(ioc)),
0455 ioc->ioc_regs.ioc_fail_sync);
0456 }
0457
0458 static bfa_boolean_t
0459 bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc)
0460 {
0461 uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
0462 uint32_t sync_reqd = bfa_ioc_ct_get_sync_reqd(r32);
0463 uint32_t sync_ackd = bfa_ioc_ct_get_sync_ackd(r32);
0464 uint32_t tmp_ackd;
0465
0466 if (sync_ackd == 0)
0467 return BFA_TRUE;
0468
0469
0470
0471
0472
0473
0474
0475 tmp_ackd = sync_ackd;
0476 if ((sync_reqd & bfa_ioc_ct_sync_pos(ioc)) &&
0477 !(sync_ackd & bfa_ioc_ct_sync_pos(ioc)))
0478 sync_ackd |= bfa_ioc_ct_sync_pos(ioc);
0479
0480 if (sync_reqd == sync_ackd) {
0481 writel(bfa_ioc_ct_clear_sync_ackd(r32),
0482 ioc->ioc_regs.ioc_fail_sync);
0483 writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
0484 writel(BFI_IOC_FAIL, ioc->ioc_regs.alt_ioc_fwstate);
0485 return BFA_TRUE;
0486 }
0487
0488
0489
0490
0491
0492
0493 if (tmp_ackd != sync_ackd)
0494 writel((r32 | sync_ackd), ioc->ioc_regs.ioc_fail_sync);
0495
0496 return BFA_FALSE;
0497 }
0498
0499
0500
0501
0502 static void
0503 bfa_ioc_set_ctx_hwif(struct bfa_ioc_s *ioc, struct bfa_ioc_hwif_s *hwif)
0504 {
0505 hwif->ioc_firmware_lock = bfa_ioc_ct_firmware_lock;
0506 hwif->ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock;
0507 hwif->ioc_notify_fail = bfa_ioc_ct_notify_fail;
0508 hwif->ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
0509 hwif->ioc_sync_start = bfa_ioc_ct_sync_start;
0510 hwif->ioc_sync_join = bfa_ioc_ct_sync_join;
0511 hwif->ioc_sync_leave = bfa_ioc_ct_sync_leave;
0512 hwif->ioc_sync_ack = bfa_ioc_ct_sync_ack;
0513 hwif->ioc_sync_complete = bfa_ioc_ct_sync_complete;
0514 hwif->ioc_set_fwstate = bfa_ioc_ct_set_cur_ioc_fwstate;
0515 hwif->ioc_get_fwstate = bfa_ioc_ct_get_cur_ioc_fwstate;
0516 hwif->ioc_set_alt_fwstate = bfa_ioc_ct_set_alt_ioc_fwstate;
0517 hwif->ioc_get_alt_fwstate = bfa_ioc_ct_get_alt_ioc_fwstate;
0518 }
0519
0520
0521
0522
0523 void
0524 bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
0525 {
0526 bfa_ioc_set_ctx_hwif(ioc, &hwif_ct);
0527
0528 hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init;
0529 hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init;
0530 hwif_ct.ioc_map_port = bfa_ioc_ct_map_port;
0531 hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
0532 ioc->ioc_hwif = &hwif_ct;
0533 }
0534
0535
0536
0537
0538 void
0539 bfa_ioc_set_ct2_hwif(struct bfa_ioc_s *ioc)
0540 {
0541 bfa_ioc_set_ctx_hwif(ioc, &hwif_ct2);
0542
0543 hwif_ct2.ioc_pll_init = bfa_ioc_ct2_pll_init;
0544 hwif_ct2.ioc_reg_init = bfa_ioc_ct2_reg_init;
0545 hwif_ct2.ioc_map_port = bfa_ioc_ct2_map_port;
0546 hwif_ct2.ioc_lpu_read_stat = bfa_ioc_ct2_lpu_read_stat;
0547 hwif_ct2.ioc_isr_mode_set = NULL;
0548 ioc->ioc_hwif = &hwif_ct2;
0549 }
0550
0551
0552
0553
0554 #define HOSTFN_MSIX_DEFAULT 64
0555 #define HOSTFN_MSIX_VT_INDEX_MBOX_ERR 0x30138
0556 #define HOSTFN_MSIX_VT_OFST_NUMVT 0x3013c
0557 #define __MSIX_VT_NUMVT__MK 0x003ff800
0558 #define __MSIX_VT_NUMVT__SH 11
0559 #define __MSIX_VT_NUMVT_(_v) ((_v) << __MSIX_VT_NUMVT__SH)
0560 #define __MSIX_VT_OFST_ 0x000007ff
0561 void
0562 bfa_ioc_ct2_poweron(struct bfa_ioc_s *ioc)
0563 {
0564 void __iomem *rb = ioc->pcidev.pci_bar_kva;
0565 u32 r32;
0566
0567 r32 = readl(rb + HOSTFN_MSIX_VT_OFST_NUMVT);
0568 if (r32 & __MSIX_VT_NUMVT__MK) {
0569 writel(r32 & __MSIX_VT_OFST_,
0570 rb + HOSTFN_MSIX_VT_INDEX_MBOX_ERR);
0571 return;
0572 }
0573
0574 writel(__MSIX_VT_NUMVT_(HOSTFN_MSIX_DEFAULT - 1) |
0575 HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc),
0576 rb + HOSTFN_MSIX_VT_OFST_NUMVT);
0577 writel(HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc),
0578 rb + HOSTFN_MSIX_VT_INDEX_MBOX_ERR);
0579 }
0580
0581 bfa_status_t
0582 bfa_ioc_ct_pll_init(void __iomem *rb, enum bfi_asic_mode mode)
0583 {
0584 u32 pll_sclk, pll_fclk, r32;
0585 bfa_boolean_t fcmode = (mode == BFI_ASIC_MODE_FC);
0586
0587 pll_sclk = __APP_PLL_SCLK_LRESETN | __APP_PLL_SCLK_ENARST |
0588 __APP_PLL_SCLK_RSEL200500 | __APP_PLL_SCLK_P0_1(3U) |
0589 __APP_PLL_SCLK_JITLMT0_1(3U) |
0590 __APP_PLL_SCLK_CNTLMT0_1(1U);
0591 pll_fclk = __APP_PLL_LCLK_LRESETN | __APP_PLL_LCLK_ENARST |
0592 __APP_PLL_LCLK_RSEL200500 | __APP_PLL_LCLK_P0_1(3U) |
0593 __APP_PLL_LCLK_JITLMT0_1(3U) |
0594 __APP_PLL_LCLK_CNTLMT0_1(1U);
0595
0596 if (fcmode) {
0597 writel(0, (rb + OP_MODE));
0598 writel(__APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2 |
0599 __APP_EMS_CHANNEL_SEL, (rb + ETH_MAC_SER_REG));
0600 } else {
0601 writel(__GLOBAL_FCOE_MODE, (rb + OP_MODE));
0602 writel(__APP_EMS_REFCKBUFEN1, (rb + ETH_MAC_SER_REG));
0603 }
0604 writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG));
0605 writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG));
0606 writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
0607 writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
0608 writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
0609 writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
0610 writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
0611 writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
0612 writel(pll_sclk | __APP_PLL_SCLK_LOGIC_SOFT_RESET,
0613 rb + APP_PLL_SCLK_CTL_REG);
0614 writel(pll_fclk | __APP_PLL_LCLK_LOGIC_SOFT_RESET,
0615 rb + APP_PLL_LCLK_CTL_REG);
0616 writel(pll_sclk | __APP_PLL_SCLK_LOGIC_SOFT_RESET |
0617 __APP_PLL_SCLK_ENABLE, rb + APP_PLL_SCLK_CTL_REG);
0618 writel(pll_fclk | __APP_PLL_LCLK_LOGIC_SOFT_RESET |
0619 __APP_PLL_LCLK_ENABLE, rb + APP_PLL_LCLK_CTL_REG);
0620 readl(rb + HOSTFN0_INT_MSK);
0621 udelay(2000);
0622 writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
0623 writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
0624 writel(pll_sclk | __APP_PLL_SCLK_ENABLE, rb + APP_PLL_SCLK_CTL_REG);
0625 writel(pll_fclk | __APP_PLL_LCLK_ENABLE, rb + APP_PLL_LCLK_CTL_REG);
0626
0627 if (!fcmode) {
0628 writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0));
0629 writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1));
0630 }
0631 r32 = readl((rb + PSS_CTL_REG));
0632 r32 &= ~__PSS_LMEM_RESET;
0633 writel(r32, (rb + PSS_CTL_REG));
0634 udelay(1000);
0635 if (!fcmode) {
0636 writel(0, (rb + PMM_1T_RESET_REG_P0));
0637 writel(0, (rb + PMM_1T_RESET_REG_P1));
0638 }
0639
0640 writel(__EDRAM_BISTR_START, (rb + MBIST_CTL_REG));
0641 udelay(1000);
0642 r32 = readl((rb + MBIST_STAT_REG));
0643 writel(0, (rb + MBIST_CTL_REG));
0644 return BFA_STATUS_OK;
0645 }
0646
0647 static void
0648 bfa_ioc_ct2_sclk_init(void __iomem *rb)
0649 {
0650 u32 r32;
0651
0652
0653
0654
0655 r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
0656 r32 &= ~(__APP_PLL_SCLK_ENABLE | __APP_PLL_SCLK_LRESETN);
0657 r32 |= (__APP_PLL_SCLK_ENARST | __APP_PLL_SCLK_BYPASS |
0658 __APP_PLL_SCLK_LOGIC_SOFT_RESET);
0659 writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG));
0660
0661
0662
0663
0664
0665 r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
0666 r32 &= ~(__APP_PLL_SCLK_REFCLK_SEL | __APP_PLL_SCLK_CLK_DIV2);
0667 writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG));
0668
0669
0670
0671
0672 r32 = readl((rb + CT2_CHIP_MISC_PRG));
0673 writel(r32 | __ETH_CLK_ENABLE_PORT0, (rb + CT2_CHIP_MISC_PRG));
0674
0675 r32 = readl((rb + CT2_PCIE_MISC_REG));
0676 writel(r32 | __ETH_CLK_ENABLE_PORT1, (rb + CT2_PCIE_MISC_REG));
0677
0678
0679
0680
0681 r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
0682 r32 &= (__P_SCLK_PLL_LOCK | __APP_PLL_SCLK_REFCLK_SEL |
0683 __APP_PLL_SCLK_CLK_DIV2);
0684 writel(r32 | 0x1061731b, (rb + CT2_APP_PLL_SCLK_CTL_REG));
0685
0686
0687
0688
0689 udelay(1000);
0690 }
0691
0692 static void
0693 bfa_ioc_ct2_lclk_init(void __iomem *rb)
0694 {
0695 u32 r32;
0696
0697
0698
0699
0700 r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
0701 r32 &= ~(__APP_PLL_LCLK_ENABLE | __APP_PLL_LCLK_LRESETN);
0702 r32 |= (__APP_PLL_LCLK_ENARST | __APP_PLL_LCLK_BYPASS |
0703 __APP_PLL_LCLK_LOGIC_SOFT_RESET);
0704 writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG));
0705
0706
0707
0708
0709 r32 = readl((rb + CT2_CHIP_MISC_PRG));
0710 writel(r32, (rb + CT2_CHIP_MISC_PRG));
0711
0712
0713
0714
0715 r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
0716 writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG));
0717
0718
0719
0720
0721 r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
0722 r32 &= (__P_LCLK_PLL_LOCK | __APP_LPUCLK_HALFSPEED);
0723 r32 |= 0x20c1731b;
0724 writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG));
0725
0726
0727
0728
0729 udelay(1000);
0730 }
0731
0732 static void
0733 bfa_ioc_ct2_mem_init(void __iomem *rb)
0734 {
0735 u32 r32;
0736
0737 r32 = readl((rb + PSS_CTL_REG));
0738 r32 &= ~__PSS_LMEM_RESET;
0739 writel(r32, (rb + PSS_CTL_REG));
0740 udelay(1000);
0741
0742 writel(__EDRAM_BISTR_START, (rb + CT2_MBIST_CTL_REG));
0743 udelay(1000);
0744 writel(0, (rb + CT2_MBIST_CTL_REG));
0745 }
0746
0747 static void
0748 bfa_ioc_ct2_mac_reset(void __iomem *rb)
0749 {
0750
0751 writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET),
0752 rb + CT2_CSI_MAC_CONTROL_REG(0));
0753 writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET),
0754 rb + CT2_CSI_MAC_CONTROL_REG(1));
0755 }
0756
0757 static void
0758 bfa_ioc_ct2_enable_flash(void __iomem *rb)
0759 {
0760 u32 r32;
0761
0762 r32 = readl((rb + PSS_GPIO_OUT_REG));
0763 writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG));
0764 r32 = readl((rb + PSS_GPIO_OE_REG));
0765 writel(r32 | 1, (rb + PSS_GPIO_OE_REG));
0766 }
0767
0768 #define CT2_NFC_MAX_DELAY 1000
0769 #define CT2_NFC_PAUSE_MAX_DELAY 4000
0770 #define CT2_NFC_VER_VALID 0x147
0771 #define CT2_NFC_STATE_RUNNING 0x20000001
0772 #define BFA_IOC_PLL_POLL 1000000
0773
0774 static bfa_boolean_t
0775 bfa_ioc_ct2_nfc_halted(void __iomem *rb)
0776 {
0777 u32 r32;
0778
0779 r32 = readl(rb + CT2_NFC_CSR_SET_REG);
0780 if (r32 & __NFC_CONTROLLER_HALTED)
0781 return BFA_TRUE;
0782
0783 return BFA_FALSE;
0784 }
0785
0786 static void
0787 bfa_ioc_ct2_nfc_halt(void __iomem *rb)
0788 {
0789 int i;
0790
0791 writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG);
0792 for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
0793 if (bfa_ioc_ct2_nfc_halted(rb))
0794 break;
0795 udelay(1000);
0796 }
0797 WARN_ON(!bfa_ioc_ct2_nfc_halted(rb));
0798 }
0799
0800 static void
0801 bfa_ioc_ct2_nfc_resume(void __iomem *rb)
0802 {
0803 u32 r32;
0804 int i;
0805
0806 writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_CLR_REG);
0807 for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
0808 r32 = readl(rb + CT2_NFC_CSR_SET_REG);
0809 if (!(r32 & __NFC_CONTROLLER_HALTED))
0810 return;
0811 udelay(1000);
0812 }
0813 WARN_ON(1);
0814 }
0815
0816 static void
0817 bfa_ioc_ct2_clk_reset(void __iomem *rb)
0818 {
0819 u32 r32;
0820
0821 bfa_ioc_ct2_sclk_init(rb);
0822 bfa_ioc_ct2_lclk_init(rb);
0823
0824
0825
0826
0827 r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
0828 writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
0829 (rb + CT2_APP_PLL_SCLK_CTL_REG));
0830
0831 r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
0832 writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
0833 (rb + CT2_APP_PLL_LCLK_CTL_REG));
0834
0835 }
0836
0837 static void
0838 bfa_ioc_ct2_nfc_clk_reset(void __iomem *rb)
0839 {
0840 u32 r32, i;
0841
0842 r32 = readl((rb + PSS_CTL_REG));
0843 r32 |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
0844 writel(r32, (rb + PSS_CTL_REG));
0845
0846 writel(__RESET_AND_START_SCLK_LCLK_PLLS, rb + CT2_CSI_FW_CTL_SET_REG);
0847
0848 for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
0849 r32 = readl(rb + CT2_NFC_FLASH_STS_REG);
0850
0851 if ((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS))
0852 break;
0853 }
0854 WARN_ON(!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS));
0855
0856 for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
0857 r32 = readl(rb + CT2_NFC_FLASH_STS_REG);
0858
0859 if (!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS))
0860 break;
0861 }
0862 WARN_ON((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS));
0863
0864 r32 = readl(rb + CT2_CSI_FW_CTL_REG);
0865 WARN_ON((r32 & __RESET_AND_START_SCLK_LCLK_PLLS));
0866 }
0867
0868 static void
0869 bfa_ioc_ct2_wait_till_nfc_running(void __iomem *rb)
0870 {
0871 u32 r32;
0872 int i;
0873
0874 if (bfa_ioc_ct2_nfc_halted(rb))
0875 bfa_ioc_ct2_nfc_resume(rb);
0876 for (i = 0; i < CT2_NFC_PAUSE_MAX_DELAY; i++) {
0877 r32 = readl(rb + CT2_NFC_STS_REG);
0878 if (r32 == CT2_NFC_STATE_RUNNING)
0879 return;
0880 udelay(1000);
0881 }
0882
0883 r32 = readl(rb + CT2_NFC_STS_REG);
0884 WARN_ON(!(r32 == CT2_NFC_STATE_RUNNING));
0885 }
0886
0887 bfa_status_t
0888 bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode)
0889 {
0890 u32 wgn, r32, nfc_ver;
0891
0892 wgn = readl(rb + CT2_WGN_STATUS);
0893
0894 if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
0895
0896
0897
0898 bfa_ioc_ct2_clk_reset(rb);
0899 bfa_ioc_ct2_enable_flash(rb);
0900
0901 bfa_ioc_ct2_mac_reset(rb);
0902
0903 bfa_ioc_ct2_clk_reset(rb);
0904 bfa_ioc_ct2_enable_flash(rb);
0905
0906 } else {
0907 nfc_ver = readl(rb + CT2_RSC_GPR15_REG);
0908
0909 if ((nfc_ver >= CT2_NFC_VER_VALID) &&
0910 (wgn == (__A2T_AHB_LOAD | __WGN_READY))) {
0911
0912 bfa_ioc_ct2_wait_till_nfc_running(rb);
0913
0914 bfa_ioc_ct2_nfc_clk_reset(rb);
0915 } else {
0916 bfa_ioc_ct2_nfc_halt(rb);
0917
0918 bfa_ioc_ct2_clk_reset(rb);
0919 bfa_ioc_ct2_mac_reset(rb);
0920 bfa_ioc_ct2_clk_reset(rb);
0921
0922 }
0923 }
0924
0925
0926
0927
0928
0929
0930
0931
0932 r32 = readl(rb + CT2_CHIP_MISC_PRG);
0933 writel((r32 & 0xfbffffff), (rb + CT2_CHIP_MISC_PRG));
0934
0935
0936
0937
0938
0939
0940 writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK));
0941 writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK));
0942
0943
0944 r32 = readl(rb + HOST_SEM5_REG);
0945 if (r32 & 0x1) {
0946 r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
0947 if (r32 == 1) {
0948 writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT));
0949 readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
0950 }
0951 r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
0952 if (r32 == 1) {
0953 writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT));
0954 readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
0955 }
0956 }
0957
0958 bfa_ioc_ct2_mem_init(rb);
0959
0960 writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG));
0961 writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG));
0962
0963 return BFA_STATUS_OK;
0964 }
0965
0966 static void
0967 bfa_ioc_ct_set_cur_ioc_fwstate(struct bfa_ioc_s *ioc,
0968 enum bfi_ioc_state fwstate)
0969 {
0970 writel(fwstate, ioc->ioc_regs.ioc_fwstate);
0971 }
0972
0973 static enum bfi_ioc_state
0974 bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc)
0975 {
0976 return (enum bfi_ioc_state)readl(ioc->ioc_regs.ioc_fwstate);
0977 }
0978
0979 static void
0980 bfa_ioc_ct_set_alt_ioc_fwstate(struct bfa_ioc_s *ioc,
0981 enum bfi_ioc_state fwstate)
0982 {
0983 writel(fwstate, ioc->ioc_regs.alt_ioc_fwstate);
0984 }
0985
0986 static enum bfi_ioc_state
0987 bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc)
0988 {
0989 return (enum bfi_ioc_state) readl(ioc->ioc_regs.alt_ioc_fwstate);
0990 }