diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-24 23:28:17 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 18:25:44 -0400 |
commit | 3d7fc66dcd8d510aaa46ab9b914b632bc149b05c (patch) | |
tree | 256cf906d79359a90c462b5c1d08dc1969b6b7ed /drivers/scsi | |
parent | 5a54b1d576d1880eb249e906e0c8e2ffe64506d3 (diff) |
[SCSI] bfa: Added HBA diagnostics support.
- Added diagnostics sub-module to BFA.
- Implemented interface to perform memtest/loopback test
and some other diagnostics tests.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/bfa/bfa_core.c | 16 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_defs.h | 58 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.c | 580 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.h | 141 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_modules.h | 3 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.c | 417 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.h | 47 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.c | 206 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.h | 83 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_debugfs.c | 14 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi.h | 109 |
11 files changed, 1665 insertions, 9 deletions
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index 04d362085360..e688ff72166d 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c | |||
@@ -25,6 +25,7 @@ BFA_TRC_FILE(HAL, CORE); | |||
25 | * BFA module list terminated by NULL | 25 | * BFA module list terminated by NULL |
26 | */ | 26 | */ |
27 | static struct bfa_module_s *hal_mods[] = { | 27 | static struct bfa_module_s *hal_mods[] = { |
28 | &hal_mod_fcdiag, | ||
28 | &hal_mod_sgpg, | 29 | &hal_mod_sgpg, |
29 | &hal_mod_fcport, | 30 | &hal_mod_fcport, |
30 | &hal_mod_fcxp, | 31 | &hal_mod_fcxp, |
@@ -41,7 +42,7 @@ static struct bfa_module_s *hal_mods[] = { | |||
41 | static bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = { | 42 | static bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = { |
42 | bfa_isr_unhandled, /* NONE */ | 43 | bfa_isr_unhandled, /* NONE */ |
43 | bfa_isr_unhandled, /* BFI_MC_IOC */ | 44 | bfa_isr_unhandled, /* BFI_MC_IOC */ |
44 | bfa_isr_unhandled, /* BFI_MC_DIAG */ | 45 | bfa_fcdiag_intr, /* BFI_MC_DIAG */ |
45 | bfa_isr_unhandled, /* BFI_MC_FLASH */ | 46 | bfa_isr_unhandled, /* BFI_MC_FLASH */ |
46 | bfa_isr_unhandled, /* BFI_MC_CEE */ | 47 | bfa_isr_unhandled, /* BFI_MC_CEE */ |
47 | bfa_fcport_isr, /* BFI_MC_FCPORT */ | 48 | bfa_fcport_isr, /* BFI_MC_FCPORT */ |
@@ -143,6 +144,16 @@ bfa_com_flash_attach(struct bfa_s *bfa, bfa_boolean_t mincfg) | |||
143 | flash_dma->dma_curp, mincfg); | 144 | flash_dma->dma_curp, mincfg); |
144 | } | 145 | } |
145 | 146 | ||
147 | static void | ||
148 | bfa_com_diag_attach(struct bfa_s *bfa) | ||
149 | { | ||
150 | struct bfa_diag_s *diag = BFA_DIAG_MOD(bfa); | ||
151 | struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa); | ||
152 | |||
153 | bfa_diag_attach(diag, &bfa->ioc, bfa, bfa_fcport_beacon, bfa->trcmod); | ||
154 | bfa_diag_memclaim(diag, diag_dma->kva_curp, diag_dma->dma_curp); | ||
155 | } | ||
156 | |||
146 | /* | 157 | /* |
147 | * BFA IOC FC related definitions | 158 | * BFA IOC FC related definitions |
148 | */ | 159 | */ |
@@ -1383,6 +1394,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, | |||
1383 | struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa); | 1394 | struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa); |
1384 | struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa); | 1395 | struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa); |
1385 | struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa); | 1396 | struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa); |
1397 | struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa); | ||
1386 | 1398 | ||
1387 | WARN_ON((cfg == NULL) || (meminfo == NULL)); | 1399 | WARN_ON((cfg == NULL) || (meminfo == NULL)); |
1388 | 1400 | ||
@@ -1404,6 +1416,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, | |||
1404 | bfa_mem_dma_setup(meminfo, sfp_dma, bfa_sfp_meminfo()); | 1416 | bfa_mem_dma_setup(meminfo, sfp_dma, bfa_sfp_meminfo()); |
1405 | bfa_mem_dma_setup(meminfo, flash_dma, | 1417 | bfa_mem_dma_setup(meminfo, flash_dma, |
1406 | bfa_flash_meminfo(cfg->drvcfg.min_cfg)); | 1418 | bfa_flash_meminfo(cfg->drvcfg.min_cfg)); |
1419 | bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo()); | ||
1407 | } | 1420 | } |
1408 | 1421 | ||
1409 | /* | 1422 | /* |
@@ -1474,6 +1487,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
1474 | bfa_com_cee_attach(bfa); | 1487 | bfa_com_cee_attach(bfa); |
1475 | bfa_com_sfp_attach(bfa); | 1488 | bfa_com_sfp_attach(bfa); |
1476 | bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg); | 1489 | bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg); |
1490 | bfa_com_diag_attach(bfa); | ||
1477 | } | 1491 | } |
1478 | 1492 | ||
1479 | /* | 1493 | /* |
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index 97ad07c4aee0..ddf13d74e4b0 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h | |||
@@ -132,7 +132,9 @@ enum bfa_status { | |||
132 | BFA_STATUS_EPROTOCOL = 6, /* Protocol error */ | 132 | BFA_STATUS_EPROTOCOL = 6, /* Protocol error */ |
133 | BFA_STATUS_SFP_UNSUPP = 10, /* Unsupported SFP - Replace SFP */ | 133 | BFA_STATUS_SFP_UNSUPP = 10, /* Unsupported SFP - Replace SFP */ |
134 | BFA_STATUS_UNKNOWN_VFID = 11, /* VF_ID not found */ | 134 | BFA_STATUS_UNKNOWN_VFID = 11, /* VF_ID not found */ |
135 | BFA_STATUS_DATACORRUPTED = 12, /* Diag returned data corrupted */ | ||
135 | BFA_STATUS_DEVBUSY = 13, /* Device busy - Retry operation */ | 136 | BFA_STATUS_DEVBUSY = 13, /* Device busy - Retry operation */ |
137 | BFA_STATUS_HDMA_FAILED = 16, /* Host dma failed contact support */ | ||
136 | BFA_STATUS_FLASH_BAD_LEN = 17, /* Flash bad length */ | 138 | BFA_STATUS_FLASH_BAD_LEN = 17, /* Flash bad length */ |
137 | BFA_STATUS_UNKNOWN_LWWN = 18, /* LPORT PWWN not found */ | 139 | BFA_STATUS_UNKNOWN_LWWN = 18, /* LPORT PWWN not found */ |
138 | BFA_STATUS_UNKNOWN_RWWN = 19, /* RPORT PWWN not found */ | 140 | BFA_STATUS_UNKNOWN_RWWN = 19, /* RPORT PWWN not found */ |
@@ -140,19 +142,25 @@ enum bfa_status { | |||
140 | BFA_STATUS_VPORT_MAX = 22, /* Reached max VPORT supported limit */ | 142 | BFA_STATUS_VPORT_MAX = 22, /* Reached max VPORT supported limit */ |
141 | BFA_STATUS_UNSUPP_SPEED = 23, /* Invalid Speed Check speed setting */ | 143 | BFA_STATUS_UNSUPP_SPEED = 23, /* Invalid Speed Check speed setting */ |
142 | BFA_STATUS_INVLD_DFSZ = 24, /* Invalid Max data field size */ | 144 | BFA_STATUS_INVLD_DFSZ = 24, /* Invalid Max data field size */ |
145 | BFA_STATUS_CMD_NOTSUPP = 26, /* Command/API not supported */ | ||
143 | BFA_STATUS_FABRIC_RJT = 29, /* Reject from attached fabric */ | 146 | BFA_STATUS_FABRIC_RJT = 29, /* Reject from attached fabric */ |
144 | BFA_STATUS_PORT_OFFLINE = 34, /* Port is not online */ | 147 | BFA_STATUS_PORT_OFFLINE = 34, /* Port is not online */ |
145 | BFA_STATUS_VPORT_WWN_BP = 46, /* WWN is same as base port's WWN */ | 148 | BFA_STATUS_VPORT_WWN_BP = 46, /* WWN is same as base port's WWN */ |
149 | BFA_STATUS_PORT_NOT_DISABLED = 47, /* Port not disabled disable port */ | ||
146 | BFA_STATUS_NO_FCPIM_NEXUS = 52, /* No FCP Nexus exists with the rport */ | 150 | BFA_STATUS_NO_FCPIM_NEXUS = 52, /* No FCP Nexus exists with the rport */ |
147 | BFA_STATUS_IOC_FAILURE = 56, /* IOC failure - Retry, if persists | 151 | BFA_STATUS_IOC_FAILURE = 56, /* IOC failure - Retry, if persists |
148 | * contact support */ | 152 | * contact support */ |
149 | BFA_STATUS_INVALID_WWN = 57, /* Invalid WWN */ | 153 | BFA_STATUS_INVALID_WWN = 57, /* Invalid WWN */ |
154 | BFA_STATUS_ADAPTER_ENABLED = 60, /* Adapter is not disabled */ | ||
150 | BFA_STATUS_IOC_NON_OP = 61, /* IOC is not operational */ | 155 | BFA_STATUS_IOC_NON_OP = 61, /* IOC is not operational */ |
151 | BFA_STATUS_VERSION_FAIL = 70, /* Application/Driver version mismatch */ | 156 | BFA_STATUS_VERSION_FAIL = 70, /* Application/Driver version mismatch */ |
152 | BFA_STATUS_DIAG_BUSY = 71, /* diag busy */ | 157 | BFA_STATUS_DIAG_BUSY = 71, /* diag busy */ |
158 | BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */ | ||
153 | BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */ | 159 | BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */ |
154 | BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */ | 160 | BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */ |
155 | BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */ | 161 | BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */ |
162 | BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */ | ||
163 | BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */ | ||
156 | BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */ | 164 | BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */ |
157 | BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot | 165 | BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot |
158 | * configuration */ | 166 | * configuration */ |
@@ -881,6 +889,56 @@ struct bfa_flash_attr_s { | |||
881 | struct bfa_flash_part_attr_s part[BFA_FLASH_PART_MAX]; | 889 | struct bfa_flash_part_attr_s part[BFA_FLASH_PART_MAX]; |
882 | }; | 890 | }; |
883 | 891 | ||
892 | /* | ||
893 | * DIAG module specific | ||
894 | */ | ||
895 | #define LB_PATTERN_DEFAULT 0xB5B5B5B5 | ||
896 | #define QTEST_CNT_DEFAULT 10 | ||
897 | #define QTEST_PAT_DEFAULT LB_PATTERN_DEFAULT | ||
898 | |||
899 | struct bfa_diag_memtest_s { | ||
900 | u8 algo; | ||
901 | u8 rsvd[7]; | ||
902 | }; | ||
903 | |||
904 | struct bfa_diag_memtest_result { | ||
905 | u32 status; | ||
906 | u32 addr; | ||
907 | u32 exp; /* expect value read from reg */ | ||
908 | u32 act; /* actually value read */ | ||
909 | u32 err_status; /* error status reg */ | ||
910 | u32 err_status1; /* extra error info reg */ | ||
911 | u32 err_addr; /* error address reg */ | ||
912 | u8 algo; | ||
913 | u8 rsv[3]; | ||
914 | }; | ||
915 | |||
916 | struct bfa_diag_loopback_result_s { | ||
917 | u32 numtxmfrm; /* no. of transmit frame */ | ||
918 | u32 numosffrm; /* no. of outstanding frame */ | ||
919 | u32 numrcvfrm; /* no. of received good frame */ | ||
920 | u32 badfrminf; /* mis-match info */ | ||
921 | u32 badfrmnum; /* mis-match fram number */ | ||
922 | u8 status; /* loopback test result */ | ||
923 | u8 rsvd[3]; | ||
924 | }; | ||
925 | |||
926 | struct bfa_diag_ledtest_s { | ||
927 | u32 cmd; /* bfa_led_op_t */ | ||
928 | u32 color; /* bfa_led_color_t */ | ||
929 | u16 freq; /* no. of blinks every 10 secs */ | ||
930 | u8 led; /* bitmap of LEDs to be tested */ | ||
931 | u8 rsvd[5]; | ||
932 | }; | ||
933 | |||
934 | struct bfa_diag_loopback_s { | ||
935 | u32 loopcnt; | ||
936 | u32 pattern; | ||
937 | u8 lb_mode; /* bfa_port_opmode_t */ | ||
938 | u8 speed; /* bfa_port_speed_t */ | ||
939 | u8 rsvd[2]; | ||
940 | }; | ||
941 | |||
884 | #pragma pack() | 942 | #pragma pack() |
885 | 943 | ||
886 | #endif /* __BFA_DEFS_H__ */ | 944 | #endif /* __BFA_DEFS_H__ */ |
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 150607324132..31467780b619 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
@@ -4315,3 +4315,583 @@ bfa_flash_read_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, | |||
4315 | 4315 | ||
4316 | return BFA_STATUS_OK; | 4316 | return BFA_STATUS_OK; |
4317 | } | 4317 | } |
4318 | |||
4319 | /* | ||
4320 | * DIAG module specific | ||
4321 | */ | ||
4322 | |||
4323 | #define BFA_DIAG_MEMTEST_TOV 50000 /* memtest timeout in msec */ | ||
4324 | #define BFA_DIAG_FWPING_TOV 1000 /* msec */ | ||
4325 | |||
4326 | /* IOC event handler */ | ||
4327 | static void | ||
4328 | bfa_diag_notify(void *diag_arg, enum bfa_ioc_event_e event) | ||
4329 | { | ||
4330 | struct bfa_diag_s *diag = diag_arg; | ||
4331 | |||
4332 | bfa_trc(diag, event); | ||
4333 | bfa_trc(diag, diag->block); | ||
4334 | bfa_trc(diag, diag->fwping.lock); | ||
4335 | bfa_trc(diag, diag->tsensor.lock); | ||
4336 | |||
4337 | switch (event) { | ||
4338 | case BFA_IOC_E_DISABLED: | ||
4339 | case BFA_IOC_E_FAILED: | ||
4340 | if (diag->fwping.lock) { | ||
4341 | diag->fwping.status = BFA_STATUS_IOC_FAILURE; | ||
4342 | diag->fwping.cbfn(diag->fwping.cbarg, | ||
4343 | diag->fwping.status); | ||
4344 | diag->fwping.lock = 0; | ||
4345 | } | ||
4346 | |||
4347 | if (diag->tsensor.lock) { | ||
4348 | diag->tsensor.status = BFA_STATUS_IOC_FAILURE; | ||
4349 | diag->tsensor.cbfn(diag->tsensor.cbarg, | ||
4350 | diag->tsensor.status); | ||
4351 | diag->tsensor.lock = 0; | ||
4352 | } | ||
4353 | |||
4354 | if (diag->block) { | ||
4355 | if (diag->timer_active) { | ||
4356 | bfa_timer_stop(&diag->timer); | ||
4357 | diag->timer_active = 0; | ||
4358 | } | ||
4359 | |||
4360 | diag->status = BFA_STATUS_IOC_FAILURE; | ||
4361 | diag->cbfn(diag->cbarg, diag->status); | ||
4362 | diag->block = 0; | ||
4363 | } | ||
4364 | break; | ||
4365 | |||
4366 | default: | ||
4367 | break; | ||
4368 | } | ||
4369 | } | ||
4370 | |||
4371 | static void | ||
4372 | bfa_diag_memtest_done(void *cbarg) | ||
4373 | { | ||
4374 | struct bfa_diag_s *diag = cbarg; | ||
4375 | struct bfa_ioc_s *ioc = diag->ioc; | ||
4376 | struct bfa_diag_memtest_result *res = diag->result; | ||
4377 | u32 loff = BFI_BOOT_MEMTEST_RES_ADDR; | ||
4378 | u32 pgnum, pgoff, i; | ||
4379 | |||
4380 | pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); | ||
4381 | pgoff = PSS_SMEM_PGOFF(loff); | ||
4382 | |||
4383 | writel(pgnum, ioc->ioc_regs.host_page_num_fn); | ||
4384 | |||
4385 | for (i = 0; i < (sizeof(struct bfa_diag_memtest_result) / | ||
4386 | sizeof(u32)); i++) { | ||
4387 | /* read test result from smem */ | ||
4388 | *((u32 *) res + i) = | ||
4389 | bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); | ||
4390 | loff += sizeof(u32); | ||
4391 | } | ||
4392 | |||
4393 | /* Reset IOC fwstates to BFI_IOC_UNINIT */ | ||
4394 | bfa_ioc_reset_fwstate(ioc); | ||
4395 | |||
4396 | res->status = swab32(res->status); | ||
4397 | bfa_trc(diag, res->status); | ||
4398 | |||
4399 | if (res->status == BFI_BOOT_MEMTEST_RES_SIG) | ||
4400 | diag->status = BFA_STATUS_OK; | ||
4401 | else { | ||
4402 | diag->status = BFA_STATUS_MEMTEST_FAILED; | ||
4403 | res->addr = swab32(res->addr); | ||
4404 | res->exp = swab32(res->exp); | ||
4405 | res->act = swab32(res->act); | ||
4406 | res->err_status = swab32(res->err_status); | ||
4407 | res->err_status1 = swab32(res->err_status1); | ||
4408 | res->err_addr = swab32(res->err_addr); | ||
4409 | bfa_trc(diag, res->addr); | ||
4410 | bfa_trc(diag, res->exp); | ||
4411 | bfa_trc(diag, res->act); | ||
4412 | bfa_trc(diag, res->err_status); | ||
4413 | bfa_trc(diag, res->err_status1); | ||
4414 | bfa_trc(diag, res->err_addr); | ||
4415 | } | ||
4416 | diag->timer_active = 0; | ||
4417 | diag->cbfn(diag->cbarg, diag->status); | ||
4418 | diag->block = 0; | ||
4419 | } | ||
4420 | |||
4421 | /* | ||
4422 | * Firmware ping | ||
4423 | */ | ||
4424 | |||
4425 | /* | ||
4426 | * Perform DMA test directly | ||
4427 | */ | ||
4428 | static void | ||
4429 | diag_fwping_send(struct bfa_diag_s *diag) | ||
4430 | { | ||
4431 | struct bfi_diag_fwping_req_s *fwping_req; | ||
4432 | u32 i; | ||
4433 | |||
4434 | bfa_trc(diag, diag->fwping.dbuf_pa); | ||
4435 | |||
4436 | /* fill DMA area with pattern */ | ||
4437 | for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++) | ||
4438 | *((u32 *)diag->fwping.dbuf_kva + i) = diag->fwping.data; | ||
4439 | |||
4440 | /* Fill mbox msg */ | ||
4441 | fwping_req = (struct bfi_diag_fwping_req_s *)diag->fwping.mbcmd.msg; | ||
4442 | |||
4443 | /* Setup SG list */ | ||
4444 | bfa_alen_set(&fwping_req->alen, BFI_DIAG_DMA_BUF_SZ, | ||
4445 | diag->fwping.dbuf_pa); | ||
4446 | /* Set up dma count */ | ||
4447 | fwping_req->count = cpu_to_be32(diag->fwping.count); | ||
4448 | /* Set up data pattern */ | ||
4449 | fwping_req->data = diag->fwping.data; | ||
4450 | |||
4451 | /* build host command */ | ||
4452 | bfi_h2i_set(fwping_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_FWPING, | ||
4453 | bfa_ioc_portid(diag->ioc)); | ||
4454 | |||
4455 | /* send mbox cmd */ | ||
4456 | bfa_ioc_mbox_queue(diag->ioc, &diag->fwping.mbcmd); | ||
4457 | } | ||
4458 | |||
4459 | static void | ||
4460 | diag_fwping_comp(struct bfa_diag_s *diag, | ||
4461 | struct bfi_diag_fwping_rsp_s *diag_rsp) | ||
4462 | { | ||
4463 | u32 rsp_data = diag_rsp->data; | ||
4464 | u8 rsp_dma_status = diag_rsp->dma_status; | ||
4465 | |||
4466 | bfa_trc(diag, rsp_data); | ||
4467 | bfa_trc(diag, rsp_dma_status); | ||
4468 | |||
4469 | if (rsp_dma_status == BFA_STATUS_OK) { | ||
4470 | u32 i, pat; | ||
4471 | pat = (diag->fwping.count & 0x1) ? ~(diag->fwping.data) : | ||
4472 | diag->fwping.data; | ||
4473 | /* Check mbox data */ | ||
4474 | if (diag->fwping.data != rsp_data) { | ||
4475 | bfa_trc(diag, rsp_data); | ||
4476 | diag->fwping.result->dmastatus = | ||
4477 | BFA_STATUS_DATACORRUPTED; | ||
4478 | diag->fwping.status = BFA_STATUS_DATACORRUPTED; | ||
4479 | diag->fwping.cbfn(diag->fwping.cbarg, | ||
4480 | diag->fwping.status); | ||
4481 | diag->fwping.lock = 0; | ||
4482 | return; | ||
4483 | } | ||
4484 | /* Check dma pattern */ | ||
4485 | for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++) { | ||
4486 | if (*((u32 *)diag->fwping.dbuf_kva + i) != pat) { | ||
4487 | bfa_trc(diag, i); | ||
4488 | bfa_trc(diag, pat); | ||
4489 | bfa_trc(diag, | ||
4490 | *((u32 *)diag->fwping.dbuf_kva + i)); | ||
4491 | diag->fwping.result->dmastatus = | ||
4492 | BFA_STATUS_DATACORRUPTED; | ||
4493 | diag->fwping.status = BFA_STATUS_DATACORRUPTED; | ||
4494 | diag->fwping.cbfn(diag->fwping.cbarg, | ||
4495 | diag->fwping.status); | ||
4496 | diag->fwping.lock = 0; | ||
4497 | return; | ||
4498 | } | ||
4499 | } | ||
4500 | diag->fwping.result->dmastatus = BFA_STATUS_OK; | ||
4501 | diag->fwping.status = BFA_STATUS_OK; | ||
4502 | diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status); | ||
4503 | diag->fwping.lock = 0; | ||
4504 | } else { | ||
4505 | diag->fwping.status = BFA_STATUS_HDMA_FAILED; | ||
4506 | diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status); | ||
4507 | diag->fwping.lock = 0; | ||
4508 | } | ||
4509 | } | ||
4510 | |||
4511 | /* | ||
4512 | * Temperature Sensor | ||
4513 | */ | ||
4514 | |||
4515 | static void | ||
4516 | diag_tempsensor_send(struct bfa_diag_s *diag) | ||
4517 | { | ||
4518 | struct bfi_diag_ts_req_s *msg; | ||
4519 | |||
4520 | msg = (struct bfi_diag_ts_req_s *)diag->tsensor.mbcmd.msg; | ||
4521 | bfa_trc(diag, msg->temp); | ||
4522 | /* build host command */ | ||
4523 | bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_TEMPSENSOR, | ||
4524 | bfa_ioc_portid(diag->ioc)); | ||
4525 | /* send mbox cmd */ | ||
4526 | bfa_ioc_mbox_queue(diag->ioc, &diag->tsensor.mbcmd); | ||
4527 | } | ||
4528 | |||
4529 | static void | ||
4530 | diag_tempsensor_comp(struct bfa_diag_s *diag, bfi_diag_ts_rsp_t *rsp) | ||
4531 | { | ||
4532 | if (!diag->tsensor.lock) { | ||
4533 | /* receiving response after ioc failure */ | ||
4534 | bfa_trc(diag, diag->tsensor.lock); | ||
4535 | return; | ||
4536 | } | ||
4537 | |||
4538 | /* | ||
4539 | * ASIC junction tempsensor is a reg read operation | ||
4540 | * it will always return OK | ||
4541 | */ | ||
4542 | diag->tsensor.temp->temp = be16_to_cpu(rsp->temp); | ||
4543 | diag->tsensor.temp->ts_junc = rsp->ts_junc; | ||
4544 | diag->tsensor.temp->ts_brd = rsp->ts_brd; | ||
4545 | diag->tsensor.temp->status = BFA_STATUS_OK; | ||
4546 | |||
4547 | if (rsp->ts_brd) { | ||
4548 | if (rsp->status == BFA_STATUS_OK) { | ||
4549 | diag->tsensor.temp->brd_temp = | ||
4550 | be16_to_cpu(rsp->brd_temp); | ||
4551 | } else { | ||
4552 | bfa_trc(diag, rsp->status); | ||
4553 | diag->tsensor.temp->brd_temp = 0; | ||
4554 | diag->tsensor.temp->status = BFA_STATUS_DEVBUSY; | ||
4555 | } | ||
4556 | } | ||
4557 | bfa_trc(diag, rsp->ts_junc); | ||
4558 | bfa_trc(diag, rsp->temp); | ||
4559 | bfa_trc(diag, rsp->ts_brd); | ||
4560 | bfa_trc(diag, rsp->brd_temp); | ||
4561 | diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status); | ||
4562 | diag->tsensor.lock = 0; | ||
4563 | } | ||
4564 | |||
4565 | /* | ||
4566 | * LED Test command | ||
4567 | */ | ||
4568 | static void | ||
4569 | diag_ledtest_send(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest) | ||
4570 | { | ||
4571 | struct bfi_diag_ledtest_req_s *msg; | ||
4572 | |||
4573 | msg = (struct bfi_diag_ledtest_req_s *)diag->ledtest.mbcmd.msg; | ||
4574 | /* build host command */ | ||
4575 | bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LEDTEST, | ||
4576 | bfa_ioc_portid(diag->ioc)); | ||
4577 | |||
4578 | /* | ||
4579 | * convert the freq from N blinks per 10 sec to | ||
4580 | * crossbow ontime value. We do it here because division is need | ||
4581 | */ | ||
4582 | if (ledtest->freq) | ||
4583 | ledtest->freq = 500 / ledtest->freq; | ||
4584 | |||
4585 | if (ledtest->freq == 0) | ||
4586 | ledtest->freq = 1; | ||
4587 | |||
4588 | bfa_trc(diag, ledtest->freq); | ||
4589 | /* mcpy(&ledtest_req->req, ledtest, sizeof(bfa_diag_ledtest_t)); */ | ||
4590 | msg->cmd = (u8) ledtest->cmd; | ||
4591 | msg->color = (u8) ledtest->color; | ||
4592 | msg->portid = bfa_ioc_portid(diag->ioc); | ||
4593 | msg->led = ledtest->led; | ||
4594 | msg->freq = cpu_to_be16(ledtest->freq); | ||
4595 | |||
4596 | /* send mbox cmd */ | ||
4597 | bfa_ioc_mbox_queue(diag->ioc, &diag->ledtest.mbcmd); | ||
4598 | } | ||
4599 | |||
4600 | static void | ||
4601 | diag_ledtest_comp(struct bfa_diag_s *diag, struct bfi_diag_ledtest_rsp_s * msg) | ||
4602 | { | ||
4603 | bfa_trc(diag, diag->ledtest.lock); | ||
4604 | diag->ledtest.lock = BFA_FALSE; | ||
4605 | /* no bfa_cb_queue is needed because driver is not waiting */ | ||
4606 | } | ||
4607 | |||
4608 | /* | ||
4609 | * Port beaconing | ||
4610 | */ | ||
4611 | static void | ||
4612 | diag_portbeacon_send(struct bfa_diag_s *diag, bfa_boolean_t beacon, u32 sec) | ||
4613 | { | ||
4614 | struct bfi_diag_portbeacon_req_s *msg; | ||
4615 | |||
4616 | msg = (struct bfi_diag_portbeacon_req_s *)diag->beacon.mbcmd.msg; | ||
4617 | /* build host command */ | ||
4618 | bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_PORTBEACON, | ||
4619 | bfa_ioc_portid(diag->ioc)); | ||
4620 | msg->beacon = beacon; | ||
4621 | msg->period = cpu_to_be32(sec); | ||
4622 | /* send mbox cmd */ | ||
4623 | bfa_ioc_mbox_queue(diag->ioc, &diag->beacon.mbcmd); | ||
4624 | } | ||
4625 | |||
4626 | static void | ||
4627 | diag_portbeacon_comp(struct bfa_diag_s *diag) | ||
4628 | { | ||
4629 | bfa_trc(diag, diag->beacon.state); | ||
4630 | diag->beacon.state = BFA_FALSE; | ||
4631 | if (diag->cbfn_beacon) | ||
4632 | diag->cbfn_beacon(diag->dev, BFA_FALSE, diag->beacon.link_e2e); | ||
4633 | } | ||
4634 | |||
4635 | /* | ||
4636 | * Diag hmbox handler | ||
4637 | */ | ||
4638 | void | ||
4639 | bfa_diag_intr(void *diagarg, struct bfi_mbmsg_s *msg) | ||
4640 | { | ||
4641 | struct bfa_diag_s *diag = diagarg; | ||
4642 | |||
4643 | switch (msg->mh.msg_id) { | ||
4644 | case BFI_DIAG_I2H_PORTBEACON: | ||
4645 | diag_portbeacon_comp(diag); | ||
4646 | break; | ||
4647 | case BFI_DIAG_I2H_FWPING: | ||
4648 | diag_fwping_comp(diag, (struct bfi_diag_fwping_rsp_s *) msg); | ||
4649 | break; | ||
4650 | case BFI_DIAG_I2H_TEMPSENSOR: | ||
4651 | diag_tempsensor_comp(diag, (bfi_diag_ts_rsp_t *) msg); | ||
4652 | break; | ||
4653 | case BFI_DIAG_I2H_LEDTEST: | ||
4654 | diag_ledtest_comp(diag, (struct bfi_diag_ledtest_rsp_s *) msg); | ||
4655 | break; | ||
4656 | default: | ||
4657 | bfa_trc(diag, msg->mh.msg_id); | ||
4658 | WARN_ON(1); | ||
4659 | } | ||
4660 | } | ||
4661 | |||
4662 | /* | ||
4663 | * Gen RAM Test | ||
4664 | * | ||
4665 | * @param[in] *diag - diag data struct | ||
4666 | * @param[in] *memtest - mem test params input from upper layer, | ||
4667 | * @param[in] pattern - mem test pattern | ||
4668 | * @param[in] *result - mem test result | ||
4669 | * @param[in] cbfn - mem test callback functioin | ||
4670 | * @param[in] cbarg - callback functioin arg | ||
4671 | * | ||
4672 | * @param[out] | ||
4673 | */ | ||
4674 | bfa_status_t | ||
4675 | bfa_diag_memtest(struct bfa_diag_s *diag, struct bfa_diag_memtest_s *memtest, | ||
4676 | u32 pattern, struct bfa_diag_memtest_result *result, | ||
4677 | bfa_cb_diag_t cbfn, void *cbarg) | ||
4678 | { | ||
4679 | bfa_trc(diag, pattern); | ||
4680 | |||
4681 | if (!bfa_ioc_adapter_is_disabled(diag->ioc)) | ||
4682 | return BFA_STATUS_ADAPTER_ENABLED; | ||
4683 | |||
4684 | /* check to see if there is another destructive diag cmd running */ | ||
4685 | if (diag->block) { | ||
4686 | bfa_trc(diag, diag->block); | ||
4687 | return BFA_STATUS_DEVBUSY; | ||
4688 | } else | ||
4689 | diag->block = 1; | ||
4690 | |||
4691 | diag->result = result; | ||
4692 | diag->cbfn = cbfn; | ||
4693 | diag->cbarg = cbarg; | ||
4694 | |||
4695 | /* download memtest code and take LPU0 out of reset */ | ||
4696 | bfa_ioc_boot(diag->ioc, BFI_FWBOOT_TYPE_MEMTEST, BFI_FWBOOT_ENV_OS); | ||
4697 | |||
4698 | bfa_timer_begin(diag->ioc->timer_mod, &diag->timer, | ||
4699 | bfa_diag_memtest_done, diag, BFA_DIAG_MEMTEST_TOV); | ||
4700 | diag->timer_active = 1; | ||
4701 | return BFA_STATUS_OK; | ||
4702 | } | ||
4703 | |||
4704 | /* | ||
4705 | * DIAG firmware ping command | ||
4706 | * | ||
4707 | * @param[in] *diag - diag data struct | ||
4708 | * @param[in] cnt - dma loop count for testing PCIE | ||
4709 | * @param[in] data - data pattern to pass in fw | ||
4710 | * @param[in] *result - pt to bfa_diag_fwping_result_t data struct | ||
4711 | * @param[in] cbfn - callback function | ||
4712 | * @param[in] *cbarg - callback functioin arg | ||
4713 | * | ||
4714 | * @param[out] | ||
4715 | */ | ||
4716 | bfa_status_t | ||
4717 | bfa_diag_fwping(struct bfa_diag_s *diag, u32 cnt, u32 data, | ||
4718 | struct bfa_diag_results_fwping *result, bfa_cb_diag_t cbfn, | ||
4719 | void *cbarg) | ||
4720 | { | ||
4721 | bfa_trc(diag, cnt); | ||
4722 | bfa_trc(diag, data); | ||
4723 | |||
4724 | if (!bfa_ioc_is_operational(diag->ioc)) | ||
4725 | return BFA_STATUS_IOC_NON_OP; | ||
4726 | |||
4727 | if (bfa_asic_id_ct2(bfa_ioc_devid((diag->ioc))) && | ||
4728 | ((diag->ioc)->clscode == BFI_PCIFN_CLASS_ETH)) | ||
4729 | return BFA_STATUS_CMD_NOTSUPP; | ||
4730 | |||
4731 | /* check to see if there is another destructive diag cmd running */ | ||
4732 | if (diag->block || diag->fwping.lock) { | ||
4733 | bfa_trc(diag, diag->block); | ||
4734 | bfa_trc(diag, diag->fwping.lock); | ||
4735 | return BFA_STATUS_DEVBUSY; | ||
4736 | } | ||
4737 | |||
4738 | /* Initialization */ | ||
4739 | diag->fwping.lock = 1; | ||
4740 | diag->fwping.cbfn = cbfn; | ||
4741 | diag->fwping.cbarg = cbarg; | ||
4742 | diag->fwping.result = result; | ||
4743 | diag->fwping.data = data; | ||
4744 | diag->fwping.count = cnt; | ||
4745 | |||
4746 | /* Init test results */ | ||
4747 | diag->fwping.result->data = 0; | ||
4748 | diag->fwping.result->status = BFA_STATUS_OK; | ||
4749 | |||
4750 | /* kick off the first ping */ | ||
4751 | diag_fwping_send(diag); | ||
4752 | return BFA_STATUS_OK; | ||
4753 | } | ||
4754 | |||
4755 | /* | ||
4756 | * Read Temperature Sensor | ||
4757 | * | ||
4758 | * @param[in] *diag - diag data struct | ||
4759 | * @param[in] *result - pt to bfa_diag_temp_t data struct | ||
4760 | * @param[in] cbfn - callback function | ||
4761 | * @param[in] *cbarg - callback functioin arg | ||
4762 | * | ||
4763 | * @param[out] | ||
4764 | */ | ||
4765 | bfa_status_t | ||
4766 | bfa_diag_tsensor_query(struct bfa_diag_s *diag, | ||
4767 | struct bfa_diag_results_tempsensor_s *result, | ||
4768 | bfa_cb_diag_t cbfn, void *cbarg) | ||
4769 | { | ||
4770 | /* check to see if there is a destructive diag cmd running */ | ||
4771 | if (diag->block || diag->tsensor.lock) { | ||
4772 | bfa_trc(diag, diag->block); | ||
4773 | bfa_trc(diag, diag->tsensor.lock); | ||
4774 | return BFA_STATUS_DEVBUSY; | ||
4775 | } | ||
4776 | |||
4777 | if (!bfa_ioc_is_operational(diag->ioc)) | ||
4778 | return BFA_STATUS_IOC_NON_OP; | ||
4779 | |||
4780 | /* Init diag mod params */ | ||
4781 | diag->tsensor.lock = 1; | ||
4782 | diag->tsensor.temp = result; | ||
4783 | diag->tsensor.cbfn = cbfn; | ||
4784 | diag->tsensor.cbarg = cbarg; | ||
4785 | |||
4786 | /* Send msg to fw */ | ||
4787 | diag_tempsensor_send(diag); | ||
4788 | |||
4789 | return BFA_STATUS_OK; | ||
4790 | } | ||
4791 | |||
4792 | /* | ||
4793 | * LED Test command | ||
4794 | * | ||
4795 | * @param[in] *diag - diag data struct | ||
4796 | * @param[in] *ledtest - pt to ledtest data structure | ||
4797 | * | ||
4798 | * @param[out] | ||
4799 | */ | ||
4800 | bfa_status_t | ||
4801 | bfa_diag_ledtest(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest) | ||
4802 | { | ||
4803 | bfa_trc(diag, ledtest->cmd); | ||
4804 | |||
4805 | if (!bfa_ioc_is_operational(diag->ioc)) | ||
4806 | return BFA_STATUS_IOC_NON_OP; | ||
4807 | |||
4808 | if (diag->beacon.state) | ||
4809 | return BFA_STATUS_BEACON_ON; | ||
4810 | |||
4811 | if (diag->ledtest.lock) | ||
4812 | return BFA_STATUS_LEDTEST_OP; | ||
4813 | |||
4814 | /* Send msg to fw */ | ||
4815 | diag->ledtest.lock = BFA_TRUE; | ||
4816 | diag_ledtest_send(diag, ledtest); | ||
4817 | |||
4818 | return BFA_STATUS_OK; | ||
4819 | } | ||
4820 | |||
4821 | /* | ||
4822 | * Port beaconing command | ||
4823 | * | ||
4824 | * @param[in] *diag - diag data struct | ||
4825 | * @param[in] beacon - port beaconing 1:ON 0:OFF | ||
4826 | * @param[in] link_e2e_beacon - link beaconing 1:ON 0:OFF | ||
4827 | * @param[in] sec - beaconing duration in seconds | ||
4828 | * | ||
4829 | * @param[out] | ||
4830 | */ | ||
4831 | bfa_status_t | ||
4832 | bfa_diag_beacon_port(struct bfa_diag_s *diag, bfa_boolean_t beacon, | ||
4833 | bfa_boolean_t link_e2e_beacon, uint32_t sec) | ||
4834 | { | ||
4835 | bfa_trc(diag, beacon); | ||
4836 | bfa_trc(diag, link_e2e_beacon); | ||
4837 | bfa_trc(diag, sec); | ||
4838 | |||
4839 | if (!bfa_ioc_is_operational(diag->ioc)) | ||
4840 | return BFA_STATUS_IOC_NON_OP; | ||
4841 | |||
4842 | if (diag->ledtest.lock) | ||
4843 | return BFA_STATUS_LEDTEST_OP; | ||
4844 | |||
4845 | if (diag->beacon.state && beacon) /* beacon alread on */ | ||
4846 | return BFA_STATUS_BEACON_ON; | ||
4847 | |||
4848 | diag->beacon.state = beacon; | ||
4849 | diag->beacon.link_e2e = link_e2e_beacon; | ||
4850 | if (diag->cbfn_beacon) | ||
4851 | diag->cbfn_beacon(diag->dev, beacon, link_e2e_beacon); | ||
4852 | |||
4853 | /* Send msg to fw */ | ||
4854 | diag_portbeacon_send(diag, beacon, sec); | ||
4855 | |||
4856 | return BFA_STATUS_OK; | ||
4857 | } | ||
4858 | |||
4859 | /* | ||
4860 | * Return DMA memory needed by diag module. | ||
4861 | */ | ||
4862 | u32 | ||
4863 | bfa_diag_meminfo(void) | ||
4864 | { | ||
4865 | return BFA_ROUNDUP(BFI_DIAG_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
4866 | } | ||
4867 | |||
4868 | /* | ||
4869 | * Attach virtual and physical memory for Diag. | ||
4870 | */ | ||
4871 | void | ||
4872 | bfa_diag_attach(struct bfa_diag_s *diag, struct bfa_ioc_s *ioc, void *dev, | ||
4873 | bfa_cb_diag_beacon_t cbfn_beacon, struct bfa_trc_mod_s *trcmod) | ||
4874 | { | ||
4875 | diag->dev = dev; | ||
4876 | diag->ioc = ioc; | ||
4877 | diag->trcmod = trcmod; | ||
4878 | |||
4879 | diag->block = 0; | ||
4880 | diag->cbfn = NULL; | ||
4881 | diag->cbarg = NULL; | ||
4882 | diag->result = NULL; | ||
4883 | diag->cbfn_beacon = cbfn_beacon; | ||
4884 | |||
4885 | bfa_ioc_mbox_regisr(diag->ioc, BFI_MC_DIAG, bfa_diag_intr, diag); | ||
4886 | bfa_q_qe_init(&diag->ioc_notify); | ||
4887 | bfa_ioc_notify_init(&diag->ioc_notify, bfa_diag_notify, diag); | ||
4888 | list_add_tail(&diag->ioc_notify.qe, &diag->ioc->notify_q); | ||
4889 | } | ||
4890 | |||
4891 | void | ||
4892 | bfa_diag_memclaim(struct bfa_diag_s *diag, u8 *dm_kva, u64 dm_pa) | ||
4893 | { | ||
4894 | diag->fwping.dbuf_kva = dm_kva; | ||
4895 | diag->fwping.dbuf_pa = dm_pa; | ||
4896 | memset(diag->fwping.dbuf_kva, 0, BFI_DIAG_DMA_BUF_SZ); | ||
4897 | } | ||
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index c302b996b920..5bcab540ea60 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h | |||
@@ -491,6 +491,147 @@ void bfa_flash_attach(struct bfa_flash_s *flash, struct bfa_ioc_s *ioc, | |||
491 | void bfa_flash_memclaim(struct bfa_flash_s *flash, | 491 | void bfa_flash_memclaim(struct bfa_flash_s *flash, |
492 | u8 *dm_kva, u64 dm_pa, bfa_boolean_t mincfg); | 492 | u8 *dm_kva, u64 dm_pa, bfa_boolean_t mincfg); |
493 | 493 | ||
494 | /* | ||
495 | * DIAG module specific | ||
496 | */ | ||
497 | |||
498 | typedef void (*bfa_cb_diag_t) (void *cbarg, bfa_status_t status); | ||
499 | typedef void (*bfa_cb_diag_beacon_t) (void *dev, bfa_boolean_t beacon, | ||
500 | bfa_boolean_t link_e2e_beacon); | ||
501 | |||
502 | /* | ||
503 | * Firmware ping test results | ||
504 | */ | ||
505 | struct bfa_diag_results_fwping { | ||
506 | u32 data; /* store the corrupted data */ | ||
507 | u32 status; | ||
508 | u32 dmastatus; | ||
509 | u8 rsvd[4]; | ||
510 | }; | ||
511 | |||
512 | struct bfa_diag_qtest_result_s { | ||
513 | u32 status; | ||
514 | u16 count; /* sucessful queue test count */ | ||
515 | u8 queue; | ||
516 | u8 rsvd; /* 64-bit align */ | ||
517 | }; | ||
518 | |||
519 | /* | ||
520 | * Firmware ping test results | ||
521 | */ | ||
522 | struct bfa_diag_fwping_s { | ||
523 | struct bfa_diag_results_fwping *result; | ||
524 | bfa_cb_diag_t cbfn; | ||
525 | void *cbarg; | ||
526 | u32 data; | ||
527 | u8 lock; | ||
528 | u8 rsv[3]; | ||
529 | u32 status; | ||
530 | u32 count; | ||
531 | struct bfa_mbox_cmd_s mbcmd; | ||
532 | u8 *dbuf_kva; /* dma buf virtual address */ | ||
533 | u64 dbuf_pa; /* dma buf physical address */ | ||
534 | }; | ||
535 | |||
536 | /* | ||
537 | * Temperature sensor query results | ||
538 | */ | ||
539 | struct bfa_diag_results_tempsensor_s { | ||
540 | u32 status; | ||
541 | u16 temp; /* 10-bit A/D value */ | ||
542 | u16 brd_temp; /* 9-bit board temp */ | ||
543 | u8 ts_junc; /* show junction tempsensor */ | ||
544 | u8 ts_brd; /* show board tempsensor */ | ||
545 | u8 rsvd[6]; /* keep 8 bytes alignment */ | ||
546 | }; | ||
547 | |||
548 | struct bfa_diag_tsensor_s { | ||
549 | bfa_cb_diag_t cbfn; | ||
550 | void *cbarg; | ||
551 | struct bfa_diag_results_tempsensor_s *temp; | ||
552 | u8 lock; | ||
553 | u8 rsv[3]; | ||
554 | u32 status; | ||
555 | struct bfa_mbox_cmd_s mbcmd; | ||
556 | }; | ||
557 | |||
558 | struct bfa_diag_sfpshow_s { | ||
559 | struct sfp_mem_s *sfpmem; | ||
560 | bfa_cb_diag_t cbfn; | ||
561 | void *cbarg; | ||
562 | u8 lock; | ||
563 | u8 static_data; | ||
564 | u8 rsv[2]; | ||
565 | u32 status; | ||
566 | struct bfa_mbox_cmd_s mbcmd; | ||
567 | u8 *dbuf_kva; /* dma buf virtual address */ | ||
568 | u64 dbuf_pa; /* dma buf physical address */ | ||
569 | }; | ||
570 | |||
571 | struct bfa_diag_led_s { | ||
572 | struct bfa_mbox_cmd_s mbcmd; | ||
573 | bfa_boolean_t lock; /* 1: ledtest is operating */ | ||
574 | }; | ||
575 | |||
576 | struct bfa_diag_beacon_s { | ||
577 | struct bfa_mbox_cmd_s mbcmd; | ||
578 | bfa_boolean_t state; /* port beacon state */ | ||
579 | bfa_boolean_t link_e2e; /* link beacon state */ | ||
580 | }; | ||
581 | |||
582 | struct bfa_diag_s { | ||
583 | void *dev; | ||
584 | struct bfa_ioc_s *ioc; | ||
585 | struct bfa_trc_mod_s *trcmod; | ||
586 | struct bfa_diag_fwping_s fwping; | ||
587 | struct bfa_diag_tsensor_s tsensor; | ||
588 | struct bfa_diag_sfpshow_s sfpshow; | ||
589 | struct bfa_diag_led_s ledtest; | ||
590 | struct bfa_diag_beacon_s beacon; | ||
591 | void *result; | ||
592 | struct bfa_timer_s timer; | ||
593 | bfa_cb_diag_beacon_t cbfn_beacon; | ||
594 | bfa_cb_diag_t cbfn; | ||
595 | void *cbarg; | ||
596 | u8 block; | ||
597 | u8 timer_active; | ||
598 | u8 rsvd[2]; | ||
599 | u32 status; | ||
600 | struct bfa_ioc_notify_s ioc_notify; | ||
601 | struct bfa_mem_dma_s diag_dma; | ||
602 | }; | ||
603 | |||
604 | #define BFA_DIAG_MOD(__bfa) (&(__bfa)->modules.diag_mod) | ||
605 | #define BFA_MEM_DIAG_DMA(__bfa) (&(BFA_DIAG_MOD(__bfa)->diag_dma)) | ||
606 | |||
607 | u32 bfa_diag_meminfo(void); | ||
608 | void bfa_diag_memclaim(struct bfa_diag_s *diag, u8 *dm_kva, u64 dm_pa); | ||
609 | void bfa_diag_attach(struct bfa_diag_s *diag, struct bfa_ioc_s *ioc, void *dev, | ||
610 | bfa_cb_diag_beacon_t cbfn_beacon, | ||
611 | struct bfa_trc_mod_s *trcmod); | ||
612 | bfa_status_t bfa_diag_reg_read(struct bfa_diag_s *diag, u32 offset, | ||
613 | u32 len, u32 *buf, u32 force); | ||
614 | bfa_status_t bfa_diag_reg_write(struct bfa_diag_s *diag, u32 offset, | ||
615 | u32 len, u32 value, u32 force); | ||
616 | bfa_status_t bfa_diag_tsensor_query(struct bfa_diag_s *diag, | ||
617 | struct bfa_diag_results_tempsensor_s *result, | ||
618 | bfa_cb_diag_t cbfn, void *cbarg); | ||
619 | bfa_status_t bfa_diag_fwping(struct bfa_diag_s *diag, u32 cnt, | ||
620 | u32 pattern, struct bfa_diag_results_fwping *result, | ||
621 | bfa_cb_diag_t cbfn, void *cbarg); | ||
622 | bfa_status_t bfa_diag_sfpshow(struct bfa_diag_s *diag, | ||
623 | struct sfp_mem_s *sfpmem, u8 static_data, | ||
624 | bfa_cb_diag_t cbfn, void *cbarg); | ||
625 | bfa_status_t bfa_diag_memtest(struct bfa_diag_s *diag, | ||
626 | struct bfa_diag_memtest_s *memtest, u32 pattern, | ||
627 | struct bfa_diag_memtest_result *result, | ||
628 | bfa_cb_diag_t cbfn, void *cbarg); | ||
629 | bfa_status_t bfa_diag_ledtest(struct bfa_diag_s *diag, | ||
630 | struct bfa_diag_ledtest_s *ledtest); | ||
631 | bfa_status_t bfa_diag_beacon_port(struct bfa_diag_s *diag, | ||
632 | bfa_boolean_t beacon, bfa_boolean_t link_e2e_beacon, | ||
633 | u32 sec); | ||
634 | |||
494 | #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) | 635 | #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) |
495 | #define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id) | 636 | #define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id) |
496 | #define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva) | 637 | #define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva) |
diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h index f7783f0d3267..c6b2fe7ed960 100644 --- a/drivers/scsi/bfa/bfa_modules.h +++ b/drivers/scsi/bfa/bfa_modules.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "bfa_port.h" | 29 | #include "bfa_port.h" |
30 | 30 | ||
31 | struct bfa_modules_s { | 31 | struct bfa_modules_s { |
32 | struct bfa_fcdiag_s fcdiag; /* fcdiag module */ | ||
32 | struct bfa_fcport_s fcport; /* fc port module */ | 33 | struct bfa_fcport_s fcport; /* fc port module */ |
33 | struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */ | 34 | struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */ |
34 | struct bfa_lps_mod_s lps_mod; /* fcxp module */ | 35 | struct bfa_lps_mod_s lps_mod; /* fcxp module */ |
@@ -41,6 +42,7 @@ struct bfa_modules_s { | |||
41 | struct bfa_cee_s cee; /* CEE Module */ | 42 | struct bfa_cee_s cee; /* CEE Module */ |
42 | struct bfa_sfp_s sfp; /* SFP module */ | 43 | struct bfa_sfp_s sfp; /* SFP module */ |
43 | struct bfa_flash_s flash; /* flash module */ | 44 | struct bfa_flash_s flash; /* flash module */ |
45 | struct bfa_diag_s diag_mod; /* diagnostics module */ | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | /* | 48 | /* |
@@ -119,6 +121,7 @@ struct bfa_s { | |||
119 | }; | 121 | }; |
120 | 122 | ||
121 | extern bfa_boolean_t bfa_auto_recover; | 123 | extern bfa_boolean_t bfa_auto_recover; |
124 | extern struct bfa_module_s hal_mod_fcdiag; | ||
122 | extern struct bfa_module_s hal_mod_sgpg; | 125 | extern struct bfa_module_s hal_mod_sgpg; |
123 | extern struct bfa_module_s hal_mod_fcport; | 126 | extern struct bfa_module_s hal_mod_fcport; |
124 | extern struct bfa_module_s hal_mod_fcxp; | 127 | extern struct bfa_module_s hal_mod_fcxp; |
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index d7853e698d01..21caaefce99f 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "bfa_modules.h" | 21 | #include "bfa_modules.h" |
22 | 22 | ||
23 | BFA_TRC_FILE(HAL, FCXP); | 23 | BFA_TRC_FILE(HAL, FCXP); |
24 | BFA_MODULE(fcdiag); | ||
24 | BFA_MODULE(fcxp); | 25 | BFA_MODULE(fcxp); |
25 | BFA_MODULE(sgpg); | 26 | BFA_MODULE(sgpg); |
26 | BFA_MODULE(lps); | 27 | BFA_MODULE(lps); |
@@ -3872,6 +3873,22 @@ bfa_fcport_get_ratelim_speed(struct bfa_s *bfa) | |||
3872 | 3873 | ||
3873 | } | 3874 | } |
3874 | 3875 | ||
3876 | void | ||
3877 | bfa_fcport_beacon(void *dev, bfa_boolean_t beacon, | ||
3878 | bfa_boolean_t link_e2e_beacon) | ||
3879 | { | ||
3880 | struct bfa_s *bfa = dev; | ||
3881 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | ||
3882 | |||
3883 | bfa_trc(bfa, beacon); | ||
3884 | bfa_trc(bfa, link_e2e_beacon); | ||
3885 | bfa_trc(bfa, fcport->beacon); | ||
3886 | bfa_trc(bfa, fcport->link_e2e_beacon); | ||
3887 | |||
3888 | fcport->beacon = beacon; | ||
3889 | fcport->link_e2e_beacon = link_e2e_beacon; | ||
3890 | } | ||
3891 | |||
3875 | bfa_boolean_t | 3892 | bfa_boolean_t |
3876 | bfa_fcport_is_linkup(struct bfa_s *bfa) | 3893 | bfa_fcport_is_linkup(struct bfa_s *bfa) |
3877 | { | 3894 | { |
@@ -5224,3 +5241,403 @@ bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw) | |||
5224 | list_add_tail(qe, &mod->uf_unused_q); | 5241 | list_add_tail(qe, &mod->uf_unused_q); |
5225 | } | 5242 | } |
5226 | } | 5243 | } |
5244 | |||
5245 | /* | ||
5246 | * BFA fcdiag module | ||
5247 | */ | ||
5248 | #define BFA_DIAG_QTEST_TOV 1000 /* msec */ | ||
5249 | |||
5250 | /* | ||
5251 | * Set port status to busy | ||
5252 | */ | ||
5253 | static void | ||
5254 | bfa_fcdiag_set_busy_status(struct bfa_fcdiag_s *fcdiag) | ||
5255 | { | ||
5256 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fcdiag->bfa); | ||
5257 | |||
5258 | if (fcdiag->lb.lock) | ||
5259 | fcport->diag_busy = BFA_TRUE; | ||
5260 | else | ||
5261 | fcport->diag_busy = BFA_FALSE; | ||
5262 | } | ||
5263 | |||
5264 | static void | ||
5265 | bfa_fcdiag_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, | ||
5266 | struct bfa_s *bfa) | ||
5267 | { | ||
5268 | } | ||
5269 | |||
5270 | static void | ||
5271 | bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | ||
5272 | struct bfa_pcidev_s *pcidev) | ||
5273 | { | ||
5274 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
5275 | fcdiag->bfa = bfa; | ||
5276 | fcdiag->trcmod = bfa->trcmod; | ||
5277 | /* The common DIAG attach bfa_diag_attach() will do all memory claim */ | ||
5278 | } | ||
5279 | |||
5280 | static void | ||
5281 | bfa_fcdiag_iocdisable(struct bfa_s *bfa) | ||
5282 | { | ||
5283 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
5284 | bfa_trc(fcdiag, fcdiag->lb.lock); | ||
5285 | if (fcdiag->lb.lock) { | ||
5286 | fcdiag->lb.status = BFA_STATUS_IOC_FAILURE; | ||
5287 | fcdiag->lb.cbfn(fcdiag->lb.cbarg, fcdiag->lb.status); | ||
5288 | fcdiag->lb.lock = 0; | ||
5289 | bfa_fcdiag_set_busy_status(fcdiag); | ||
5290 | } | ||
5291 | } | ||
5292 | |||
5293 | static void | ||
5294 | bfa_fcdiag_detach(struct bfa_s *bfa) | ||
5295 | { | ||
5296 | } | ||
5297 | |||
5298 | static void | ||
5299 | bfa_fcdiag_start(struct bfa_s *bfa) | ||
5300 | { | ||
5301 | } | ||
5302 | |||
5303 | static void | ||
5304 | bfa_fcdiag_stop(struct bfa_s *bfa) | ||
5305 | { | ||
5306 | } | ||
5307 | |||
5308 | static void | ||
5309 | bfa_fcdiag_queuetest_timeout(void *cbarg) | ||
5310 | { | ||
5311 | struct bfa_fcdiag_s *fcdiag = cbarg; | ||
5312 | struct bfa_diag_qtest_result_s *res = fcdiag->qtest.result; | ||
5313 | |||
5314 | bfa_trc(fcdiag, fcdiag->qtest.all); | ||
5315 | bfa_trc(fcdiag, fcdiag->qtest.count); | ||
5316 | |||
5317 | fcdiag->qtest.timer_active = 0; | ||
5318 | |||
5319 | res->status = BFA_STATUS_ETIMER; | ||
5320 | res->count = QTEST_CNT_DEFAULT - fcdiag->qtest.count; | ||
5321 | if (fcdiag->qtest.all) | ||
5322 | res->queue = fcdiag->qtest.all; | ||
5323 | |||
5324 | bfa_trc(fcdiag, BFA_STATUS_ETIMER); | ||
5325 | fcdiag->qtest.status = BFA_STATUS_ETIMER; | ||
5326 | fcdiag->qtest.cbfn(fcdiag->qtest.cbarg, fcdiag->qtest.status); | ||
5327 | fcdiag->qtest.lock = 0; | ||
5328 | } | ||
5329 | |||
5330 | static bfa_status_t | ||
5331 | bfa_fcdiag_queuetest_send(struct bfa_fcdiag_s *fcdiag) | ||
5332 | { | ||
5333 | u32 i; | ||
5334 | struct bfi_diag_qtest_req_s *req; | ||
5335 | |||
5336 | req = bfa_reqq_next(fcdiag->bfa, fcdiag->qtest.queue); | ||
5337 | if (!req) | ||
5338 | return BFA_STATUS_DEVBUSY; | ||
5339 | |||
5340 | /* build host command */ | ||
5341 | bfi_h2i_set(req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_QTEST, | ||
5342 | bfa_fn_lpu(fcdiag->bfa)); | ||
5343 | |||
5344 | for (i = 0; i < BFI_LMSG_PL_WSZ; i++) | ||
5345 | req->data[i] = QTEST_PAT_DEFAULT; | ||
5346 | |||
5347 | bfa_trc(fcdiag, fcdiag->qtest.queue); | ||
5348 | /* ring door bell */ | ||
5349 | bfa_reqq_produce(fcdiag->bfa, fcdiag->qtest.queue, req->mh); | ||
5350 | return BFA_STATUS_OK; | ||
5351 | } | ||
5352 | |||
5353 | static void | ||
5354 | bfa_fcdiag_queuetest_comp(struct bfa_fcdiag_s *fcdiag, | ||
5355 | bfi_diag_qtest_rsp_t *rsp) | ||
5356 | { | ||
5357 | struct bfa_diag_qtest_result_s *res = fcdiag->qtest.result; | ||
5358 | bfa_status_t status = BFA_STATUS_OK; | ||
5359 | int i; | ||
5360 | |||
5361 | /* Check timer, should still be active */ | ||
5362 | if (!fcdiag->qtest.timer_active) { | ||
5363 | bfa_trc(fcdiag, fcdiag->qtest.timer_active); | ||
5364 | return; | ||
5365 | } | ||
5366 | |||
5367 | /* update count */ | ||
5368 | fcdiag->qtest.count--; | ||
5369 | |||
5370 | /* Check result */ | ||
5371 | for (i = 0; i < BFI_LMSG_PL_WSZ; i++) { | ||
5372 | if (rsp->data[i] != ~(QTEST_PAT_DEFAULT)) { | ||
5373 | res->status = BFA_STATUS_DATACORRUPTED; | ||
5374 | break; | ||
5375 | } | ||
5376 | } | ||
5377 | |||
5378 | if (res->status == BFA_STATUS_OK) { | ||
5379 | if (fcdiag->qtest.count > 0) { | ||
5380 | status = bfa_fcdiag_queuetest_send(fcdiag); | ||
5381 | if (status == BFA_STATUS_OK) | ||
5382 | return; | ||
5383 | else | ||
5384 | res->status = status; | ||
5385 | } else if (fcdiag->qtest.all > 0 && | ||
5386 | fcdiag->qtest.queue < (BFI_IOC_MAX_CQS - 1)) { | ||
5387 | fcdiag->qtest.count = QTEST_CNT_DEFAULT; | ||
5388 | fcdiag->qtest.queue++; | ||
5389 | status = bfa_fcdiag_queuetest_send(fcdiag); | ||
5390 | if (status == BFA_STATUS_OK) | ||
5391 | return; | ||
5392 | else | ||
5393 | res->status = status; | ||
5394 | } | ||
5395 | } | ||
5396 | |||
5397 | /* Stop timer when we comp all queue */ | ||
5398 | if (fcdiag->qtest.timer_active) { | ||
5399 | bfa_timer_stop(&fcdiag->qtest.timer); | ||
5400 | fcdiag->qtest.timer_active = 0; | ||
5401 | } | ||
5402 | res->queue = fcdiag->qtest.queue; | ||
5403 | res->count = QTEST_CNT_DEFAULT - fcdiag->qtest.count; | ||
5404 | bfa_trc(fcdiag, res->count); | ||
5405 | bfa_trc(fcdiag, res->status); | ||
5406 | fcdiag->qtest.status = res->status; | ||
5407 | fcdiag->qtest.cbfn(fcdiag->qtest.cbarg, fcdiag->qtest.status); | ||
5408 | fcdiag->qtest.lock = 0; | ||
5409 | } | ||
5410 | |||
5411 | static void | ||
5412 | bfa_fcdiag_loopback_comp(struct bfa_fcdiag_s *fcdiag, | ||
5413 | struct bfi_diag_lb_rsp_s *rsp) | ||
5414 | { | ||
5415 | struct bfa_diag_loopback_result_s *res = fcdiag->lb.result; | ||
5416 | |||
5417 | res->numtxmfrm = be32_to_cpu(rsp->res.numtxmfrm); | ||
5418 | res->numosffrm = be32_to_cpu(rsp->res.numosffrm); | ||
5419 | res->numrcvfrm = be32_to_cpu(rsp->res.numrcvfrm); | ||
5420 | res->badfrminf = be32_to_cpu(rsp->res.badfrminf); | ||
5421 | res->badfrmnum = be32_to_cpu(rsp->res.badfrmnum); | ||
5422 | res->status = rsp->res.status; | ||
5423 | fcdiag->lb.status = rsp->res.status; | ||
5424 | bfa_trc(fcdiag, fcdiag->lb.status); | ||
5425 | fcdiag->lb.cbfn(fcdiag->lb.cbarg, fcdiag->lb.status); | ||
5426 | fcdiag->lb.lock = 0; | ||
5427 | bfa_fcdiag_set_busy_status(fcdiag); | ||
5428 | } | ||
5429 | |||
5430 | static bfa_status_t | ||
5431 | bfa_fcdiag_loopback_send(struct bfa_fcdiag_s *fcdiag, | ||
5432 | struct bfa_diag_loopback_s *loopback) | ||
5433 | { | ||
5434 | struct bfi_diag_lb_req_s *lb_req; | ||
5435 | |||
5436 | lb_req = bfa_reqq_next(fcdiag->bfa, BFA_REQQ_DIAG); | ||
5437 | if (!lb_req) | ||
5438 | return BFA_STATUS_DEVBUSY; | ||
5439 | |||
5440 | /* build host command */ | ||
5441 | bfi_h2i_set(lb_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LOOPBACK, | ||
5442 | bfa_fn_lpu(fcdiag->bfa)); | ||
5443 | |||
5444 | lb_req->lb_mode = loopback->lb_mode; | ||
5445 | lb_req->speed = loopback->speed; | ||
5446 | lb_req->loopcnt = loopback->loopcnt; | ||
5447 | lb_req->pattern = loopback->pattern; | ||
5448 | |||
5449 | /* ring door bell */ | ||
5450 | bfa_reqq_produce(fcdiag->bfa, BFA_REQQ_DIAG, lb_req->mh); | ||
5451 | |||
5452 | bfa_trc(fcdiag, loopback->lb_mode); | ||
5453 | bfa_trc(fcdiag, loopback->speed); | ||
5454 | bfa_trc(fcdiag, loopback->loopcnt); | ||
5455 | bfa_trc(fcdiag, loopback->pattern); | ||
5456 | return BFA_STATUS_OK; | ||
5457 | } | ||
5458 | |||
5459 | /* | ||
5460 | * cpe/rme intr handler | ||
5461 | */ | ||
5462 | void | ||
5463 | bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg) | ||
5464 | { | ||
5465 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
5466 | |||
5467 | switch (msg->mhdr.msg_id) { | ||
5468 | case BFI_DIAG_I2H_LOOPBACK: | ||
5469 | bfa_fcdiag_loopback_comp(fcdiag, | ||
5470 | (struct bfi_diag_lb_rsp_s *) msg); | ||
5471 | break; | ||
5472 | case BFI_DIAG_I2H_QTEST: | ||
5473 | bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); | ||
5474 | break; | ||
5475 | default: | ||
5476 | bfa_trc(fcdiag, msg->mhdr.msg_id); | ||
5477 | WARN_ON(1); | ||
5478 | } | ||
5479 | } | ||
5480 | |||
5481 | /* | ||
5482 | * Loopback test | ||
5483 | * | ||
5484 | * @param[in] *bfa - bfa data struct | ||
5485 | * @param[in] opmode - port operation mode | ||
5486 | * @param[in] speed - port speed | ||
5487 | * @param[in] lpcnt - loop count | ||
5488 | * @param[in] pat - pattern to build packet | ||
5489 | * @param[in] *result - pt to bfa_diag_loopback_result_t data struct | ||
5490 | * @param[in] cbfn - callback function | ||
5491 | * @param[in] cbarg - callback functioin arg | ||
5492 | * | ||
5493 | * @param[out] | ||
5494 | */ | ||
5495 | bfa_status_t | ||
5496 | bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode, | ||
5497 | enum bfa_port_speed speed, u32 lpcnt, u32 pat, | ||
5498 | struct bfa_diag_loopback_result_s *result, bfa_cb_diag_t cbfn, | ||
5499 | void *cbarg) | ||
5500 | { | ||
5501 | struct bfa_diag_loopback_s loopback; | ||
5502 | struct bfa_port_attr_s attr; | ||
5503 | bfa_status_t status; | ||
5504 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
5505 | |||
5506 | if (!bfa_iocfc_is_operational(bfa)) | ||
5507 | return BFA_STATUS_IOC_NON_OP; | ||
5508 | |||
5509 | /* if port is PBC disabled, return error */ | ||
5510 | if (bfa_fcport_is_pbcdisabled(bfa)) { | ||
5511 | bfa_trc(fcdiag, BFA_STATUS_PBC); | ||
5512 | return BFA_STATUS_PBC; | ||
5513 | } | ||
5514 | |||
5515 | if (bfa_fcport_is_disabled(bfa) == BFA_FALSE) { | ||
5516 | bfa_trc(fcdiag, opmode); | ||
5517 | return BFA_STATUS_PORT_NOT_DISABLED; | ||
5518 | } | ||
5519 | |||
5520 | /* Check if the speed is supported */ | ||
5521 | bfa_fcport_get_attr(bfa, &attr); | ||
5522 | bfa_trc(fcdiag, attr.speed_supported); | ||
5523 | if (speed > attr.speed_supported) | ||
5524 | return BFA_STATUS_UNSUPP_SPEED; | ||
5525 | |||
5526 | /* For Mezz card, port speed entered needs to be checked */ | ||
5527 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { | ||
5528 | if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { | ||
5529 | if ((speed == BFA_PORT_SPEED_1GBPS) && | ||
5530 | (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) | ||
5531 | return BFA_STATUS_UNSUPP_SPEED; | ||
5532 | if (!(speed == BFA_PORT_SPEED_1GBPS || | ||
5533 | speed == BFA_PORT_SPEED_2GBPS || | ||
5534 | speed == BFA_PORT_SPEED_4GBPS || | ||
5535 | speed == BFA_PORT_SPEED_8GBPS || | ||
5536 | speed == BFA_PORT_SPEED_16GBPS || | ||
5537 | speed == BFA_PORT_SPEED_AUTO)) | ||
5538 | return BFA_STATUS_UNSUPP_SPEED; | ||
5539 | } else { | ||
5540 | if (speed != BFA_PORT_SPEED_10GBPS) | ||
5541 | return BFA_STATUS_UNSUPP_SPEED; | ||
5542 | } | ||
5543 | } | ||
5544 | |||
5545 | /* check to see if there is another destructive diag cmd running */ | ||
5546 | if (fcdiag->lb.lock) { | ||
5547 | bfa_trc(fcdiag, fcdiag->lb.lock); | ||
5548 | return BFA_STATUS_DEVBUSY; | ||
5549 | } | ||
5550 | |||
5551 | fcdiag->lb.lock = 1; | ||
5552 | loopback.lb_mode = opmode; | ||
5553 | loopback.speed = speed; | ||
5554 | loopback.loopcnt = lpcnt; | ||
5555 | loopback.pattern = pat; | ||
5556 | fcdiag->lb.result = result; | ||
5557 | fcdiag->lb.cbfn = cbfn; | ||
5558 | fcdiag->lb.cbarg = cbarg; | ||
5559 | memset(result, 0, sizeof(struct bfa_diag_loopback_result_s)); | ||
5560 | bfa_fcdiag_set_busy_status(fcdiag); | ||
5561 | |||
5562 | /* Send msg to fw */ | ||
5563 | status = bfa_fcdiag_loopback_send(fcdiag, &loopback); | ||
5564 | return status; | ||
5565 | } | ||
5566 | |||
5567 | /* | ||
5568 | * DIAG queue test command | ||
5569 | * | ||
5570 | * @param[in] *bfa - bfa data struct | ||
5571 | * @param[in] force - 1: don't do ioc op checking | ||
5572 | * @param[in] queue - queue no. to test | ||
5573 | * @param[in] *result - pt to bfa_diag_qtest_result_t data struct | ||
5574 | * @param[in] cbfn - callback function | ||
5575 | * @param[in] *cbarg - callback functioin arg | ||
5576 | * | ||
5577 | * @param[out] | ||
5578 | */ | ||
5579 | bfa_status_t | ||
5580 | bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 force, u32 queue, | ||
5581 | struct bfa_diag_qtest_result_s *result, bfa_cb_diag_t cbfn, | ||
5582 | void *cbarg) | ||
5583 | { | ||
5584 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
5585 | bfa_status_t status; | ||
5586 | bfa_trc(fcdiag, force); | ||
5587 | bfa_trc(fcdiag, queue); | ||
5588 | |||
5589 | if (!force && !bfa_iocfc_is_operational(bfa)) | ||
5590 | return BFA_STATUS_IOC_NON_OP; | ||
5591 | |||
5592 | /* check to see if there is another destructive diag cmd running */ | ||
5593 | if (fcdiag->qtest.lock) { | ||
5594 | bfa_trc(fcdiag, fcdiag->qtest.lock); | ||
5595 | return BFA_STATUS_DEVBUSY; | ||
5596 | } | ||
5597 | |||
5598 | /* Initialization */ | ||
5599 | fcdiag->qtest.lock = 1; | ||
5600 | fcdiag->qtest.cbfn = cbfn; | ||
5601 | fcdiag->qtest.cbarg = cbarg; | ||
5602 | fcdiag->qtest.result = result; | ||
5603 | fcdiag->qtest.count = QTEST_CNT_DEFAULT; | ||
5604 | |||
5605 | /* Init test results */ | ||
5606 | fcdiag->qtest.result->status = BFA_STATUS_OK; | ||
5607 | fcdiag->qtest.result->count = 0; | ||
5608 | |||
5609 | /* send */ | ||
5610 | if (queue < BFI_IOC_MAX_CQS) { | ||
5611 | fcdiag->qtest.result->queue = (u8)queue; | ||
5612 | fcdiag->qtest.queue = (u8)queue; | ||
5613 | fcdiag->qtest.all = 0; | ||
5614 | } else { | ||
5615 | fcdiag->qtest.result->queue = 0; | ||
5616 | fcdiag->qtest.queue = 0; | ||
5617 | fcdiag->qtest.all = 1; | ||
5618 | } | ||
5619 | status = bfa_fcdiag_queuetest_send(fcdiag); | ||
5620 | |||
5621 | /* Start a timer */ | ||
5622 | if (status == BFA_STATUS_OK) { | ||
5623 | bfa_timer_start(bfa, &fcdiag->qtest.timer, | ||
5624 | bfa_fcdiag_queuetest_timeout, fcdiag, | ||
5625 | BFA_DIAG_QTEST_TOV); | ||
5626 | fcdiag->qtest.timer_active = 1; | ||
5627 | } | ||
5628 | return status; | ||
5629 | } | ||
5630 | |||
5631 | /* | ||
5632 | * DIAG PLB is running | ||
5633 | * | ||
5634 | * @param[in] *bfa - bfa data struct | ||
5635 | * | ||
5636 | * @param[out] | ||
5637 | */ | ||
5638 | bfa_status_t | ||
5639 | bfa_fcdiag_lb_is_running(struct bfa_s *bfa) | ||
5640 | { | ||
5641 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
5642 | return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK; | ||
5643 | } | ||
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index 4c0ac3e1a137..fbe513a671b5 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h | |||
@@ -548,6 +548,8 @@ enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); | |||
548 | 548 | ||
549 | void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn); | 549 | void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn); |
550 | bfa_boolean_t bfa_fcport_is_ratelim(struct bfa_s *bfa); | 550 | bfa_boolean_t bfa_fcport_is_ratelim(struct bfa_s *bfa); |
551 | void bfa_fcport_beacon(void *dev, bfa_boolean_t beacon, | ||
552 | bfa_boolean_t link_e2e_beacon); | ||
551 | bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa); | 553 | bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa); |
552 | bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa, | 554 | bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa, |
553 | union bfa_fcport_stats_u *stats, | 555 | union bfa_fcport_stats_u *stats, |
@@ -662,4 +664,49 @@ bfa_status_t bfa_faa_disable(struct bfa_s *bfa, | |||
662 | bfa_status_t bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr, | 664 | bfa_status_t bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr, |
663 | bfa_cb_iocfc_t cbfn, void *cbarg); | 665 | bfa_cb_iocfc_t cbfn, void *cbarg); |
664 | 666 | ||
667 | /* | ||
668 | * FC DIAG data structure | ||
669 | */ | ||
670 | struct bfa_fcdiag_qtest_s { | ||
671 | struct bfa_diag_qtest_result_s *result; | ||
672 | bfa_cb_diag_t cbfn; | ||
673 | void *cbarg; | ||
674 | struct bfa_timer_s timer; | ||
675 | u32 status; | ||
676 | u32 count; | ||
677 | u8 lock; | ||
678 | u8 queue; | ||
679 | u8 all; | ||
680 | u8 timer_active; | ||
681 | }; | ||
682 | |||
683 | struct bfa_fcdiag_lb_s { | ||
684 | bfa_cb_diag_t cbfn; | ||
685 | void *cbarg; | ||
686 | void *result; | ||
687 | bfa_boolean_t lock; | ||
688 | u32 status; | ||
689 | }; | ||
690 | |||
691 | struct bfa_fcdiag_s { | ||
692 | struct bfa_s *bfa; /* Back pointer to BFA */ | ||
693 | struct bfa_trc_mod_s *trcmod; | ||
694 | struct bfa_fcdiag_lb_s lb; | ||
695 | struct bfa_fcdiag_qtest_s qtest; | ||
696 | }; | ||
697 | |||
698 | #define BFA_FCDIAG_MOD(__bfa) (&(__bfa)->modules.fcdiag) | ||
699 | |||
700 | void bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg); | ||
701 | |||
702 | bfa_status_t bfa_fcdiag_loopback(struct bfa_s *bfa, | ||
703 | enum bfa_port_opmode opmode, | ||
704 | enum bfa_port_speed speed, u32 lpcnt, u32 pat, | ||
705 | struct bfa_diag_loopback_result_s *result, | ||
706 | bfa_cb_diag_t cbfn, void *cbarg); | ||
707 | bfa_status_t bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 ignore, | ||
708 | u32 queue, struct bfa_diag_qtest_result_s *result, | ||
709 | bfa_cb_diag_t cbfn, void *cbarg); | ||
710 | bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa); | ||
711 | |||
665 | #endif /* __BFA_SVC_H__ */ | 712 | #endif /* __BFA_SVC_H__ */ |
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 5444661f1150..a60270287064 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c | |||
@@ -1214,6 +1214,185 @@ out: | |||
1214 | return 0; | 1214 | return 0; |
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | int | ||
1218 | bfad_iocmd_diag_temp(struct bfad_s *bfad, void *cmd) | ||
1219 | { | ||
1220 | struct bfa_bsg_diag_get_temp_s *iocmd = | ||
1221 | (struct bfa_bsg_diag_get_temp_s *)cmd; | ||
1222 | struct bfad_hal_comp fcomp; | ||
1223 | unsigned long flags; | ||
1224 | |||
1225 | init_completion(&fcomp.comp); | ||
1226 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1227 | iocmd->status = bfa_diag_tsensor_query(BFA_DIAG_MOD(&bfad->bfa), | ||
1228 | &iocmd->result, bfad_hcb_comp, &fcomp); | ||
1229 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1230 | bfa_trc(bfad, iocmd->status); | ||
1231 | if (iocmd->status != BFA_STATUS_OK) | ||
1232 | goto out; | ||
1233 | wait_for_completion(&fcomp.comp); | ||
1234 | iocmd->status = fcomp.status; | ||
1235 | out: | ||
1236 | return 0; | ||
1237 | } | ||
1238 | |||
1239 | int | ||
1240 | bfad_iocmd_diag_memtest(struct bfad_s *bfad, void *cmd) | ||
1241 | { | ||
1242 | struct bfa_bsg_diag_memtest_s *iocmd = | ||
1243 | (struct bfa_bsg_diag_memtest_s *)cmd; | ||
1244 | struct bfad_hal_comp fcomp; | ||
1245 | unsigned long flags; | ||
1246 | |||
1247 | init_completion(&fcomp.comp); | ||
1248 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1249 | iocmd->status = bfa_diag_memtest(BFA_DIAG_MOD(&bfad->bfa), | ||
1250 | &iocmd->memtest, iocmd->pat, | ||
1251 | &iocmd->result, bfad_hcb_comp, &fcomp); | ||
1252 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1253 | bfa_trc(bfad, iocmd->status); | ||
1254 | if (iocmd->status != BFA_STATUS_OK) | ||
1255 | goto out; | ||
1256 | wait_for_completion(&fcomp.comp); | ||
1257 | iocmd->status = fcomp.status; | ||
1258 | out: | ||
1259 | return 0; | ||
1260 | } | ||
1261 | |||
1262 | int | ||
1263 | bfad_iocmd_diag_loopback(struct bfad_s *bfad, void *cmd) | ||
1264 | { | ||
1265 | struct bfa_bsg_diag_loopback_s *iocmd = | ||
1266 | (struct bfa_bsg_diag_loopback_s *)cmd; | ||
1267 | struct bfad_hal_comp fcomp; | ||
1268 | unsigned long flags; | ||
1269 | |||
1270 | init_completion(&fcomp.comp); | ||
1271 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1272 | iocmd->status = bfa_fcdiag_loopback(&bfad->bfa, iocmd->opmode, | ||
1273 | iocmd->speed, iocmd->lpcnt, iocmd->pat, | ||
1274 | &iocmd->result, bfad_hcb_comp, &fcomp); | ||
1275 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1276 | bfa_trc(bfad, iocmd->status); | ||
1277 | if (iocmd->status != BFA_STATUS_OK) | ||
1278 | goto out; | ||
1279 | wait_for_completion(&fcomp.comp); | ||
1280 | iocmd->status = fcomp.status; | ||
1281 | out: | ||
1282 | return 0; | ||
1283 | } | ||
1284 | |||
1285 | int | ||
1286 | bfad_iocmd_diag_fwping(struct bfad_s *bfad, void *cmd) | ||
1287 | { | ||
1288 | struct bfa_bsg_diag_fwping_s *iocmd = | ||
1289 | (struct bfa_bsg_diag_fwping_s *)cmd; | ||
1290 | struct bfad_hal_comp fcomp; | ||
1291 | unsigned long flags; | ||
1292 | |||
1293 | init_completion(&fcomp.comp); | ||
1294 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1295 | iocmd->status = bfa_diag_fwping(BFA_DIAG_MOD(&bfad->bfa), iocmd->cnt, | ||
1296 | iocmd->pattern, &iocmd->result, | ||
1297 | bfad_hcb_comp, &fcomp); | ||
1298 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1299 | bfa_trc(bfad, iocmd->status); | ||
1300 | if (iocmd->status != BFA_STATUS_OK) | ||
1301 | goto out; | ||
1302 | bfa_trc(bfad, 0x77771); | ||
1303 | wait_for_completion(&fcomp.comp); | ||
1304 | iocmd->status = fcomp.status; | ||
1305 | out: | ||
1306 | return 0; | ||
1307 | } | ||
1308 | |||
1309 | int | ||
1310 | bfad_iocmd_diag_queuetest(struct bfad_s *bfad, void *cmd) | ||
1311 | { | ||
1312 | struct bfa_bsg_diag_qtest_s *iocmd = (struct bfa_bsg_diag_qtest_s *)cmd; | ||
1313 | struct bfad_hal_comp fcomp; | ||
1314 | unsigned long flags; | ||
1315 | |||
1316 | init_completion(&fcomp.comp); | ||
1317 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1318 | iocmd->status = bfa_fcdiag_queuetest(&bfad->bfa, iocmd->force, | ||
1319 | iocmd->queue, &iocmd->result, | ||
1320 | bfad_hcb_comp, &fcomp); | ||
1321 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1322 | if (iocmd->status != BFA_STATUS_OK) | ||
1323 | goto out; | ||
1324 | wait_for_completion(&fcomp.comp); | ||
1325 | iocmd->status = fcomp.status; | ||
1326 | out: | ||
1327 | return 0; | ||
1328 | } | ||
1329 | |||
1330 | int | ||
1331 | bfad_iocmd_diag_sfp(struct bfad_s *bfad, void *cmd) | ||
1332 | { | ||
1333 | struct bfa_bsg_sfp_show_s *iocmd = | ||
1334 | (struct bfa_bsg_sfp_show_s *)cmd; | ||
1335 | struct bfad_hal_comp fcomp; | ||
1336 | unsigned long flags; | ||
1337 | |||
1338 | init_completion(&fcomp.comp); | ||
1339 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1340 | iocmd->status = bfa_sfp_show(BFA_SFP_MOD(&bfad->bfa), &iocmd->sfp, | ||
1341 | bfad_hcb_comp, &fcomp); | ||
1342 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1343 | bfa_trc(bfad, iocmd->status); | ||
1344 | if (iocmd->status != BFA_STATUS_OK) | ||
1345 | goto out; | ||
1346 | wait_for_completion(&fcomp.comp); | ||
1347 | iocmd->status = fcomp.status; | ||
1348 | bfa_trc(bfad, iocmd->status); | ||
1349 | out: | ||
1350 | return 0; | ||
1351 | } | ||
1352 | |||
1353 | int | ||
1354 | bfad_iocmd_diag_led(struct bfad_s *bfad, void *cmd) | ||
1355 | { | ||
1356 | struct bfa_bsg_diag_led_s *iocmd = (struct bfa_bsg_diag_led_s *)cmd; | ||
1357 | unsigned long flags; | ||
1358 | |||
1359 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1360 | iocmd->status = bfa_diag_ledtest(BFA_DIAG_MOD(&bfad->bfa), | ||
1361 | &iocmd->ledtest); | ||
1362 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1363 | return 0; | ||
1364 | } | ||
1365 | |||
1366 | int | ||
1367 | bfad_iocmd_diag_beacon_lport(struct bfad_s *bfad, void *cmd) | ||
1368 | { | ||
1369 | struct bfa_bsg_diag_beacon_s *iocmd = | ||
1370 | (struct bfa_bsg_diag_beacon_s *)cmd; | ||
1371 | unsigned long flags; | ||
1372 | |||
1373 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1374 | iocmd->status = bfa_diag_beacon_port(BFA_DIAG_MOD(&bfad->bfa), | ||
1375 | iocmd->beacon, iocmd->link_e2e_beacon, | ||
1376 | iocmd->second); | ||
1377 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1378 | return 0; | ||
1379 | } | ||
1380 | |||
1381 | int | ||
1382 | bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) | ||
1383 | { | ||
1384 | struct bfa_bsg_diag_lb_stat_s *iocmd = | ||
1385 | (struct bfa_bsg_diag_lb_stat_s *)cmd; | ||
1386 | unsigned long flags; | ||
1387 | |||
1388 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1389 | iocmd->status = bfa_fcdiag_lb_is_running(&bfad->bfa); | ||
1390 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1391 | bfa_trc(bfad, iocmd->status); | ||
1392 | |||
1393 | return 0; | ||
1394 | } | ||
1395 | |||
1217 | static int | 1396 | static int |
1218 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | 1397 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, |
1219 | unsigned int payload_len) | 1398 | unsigned int payload_len) |
@@ -1360,6 +1539,33 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | |||
1360 | case IOCMD_FLASH_READ_PART: | 1539 | case IOCMD_FLASH_READ_PART: |
1361 | rc = bfad_iocmd_flash_read_part(bfad, iocmd, payload_len); | 1540 | rc = bfad_iocmd_flash_read_part(bfad, iocmd, payload_len); |
1362 | break; | 1541 | break; |
1542 | case IOCMD_DIAG_TEMP: | ||
1543 | rc = bfad_iocmd_diag_temp(bfad, iocmd); | ||
1544 | break; | ||
1545 | case IOCMD_DIAG_MEMTEST: | ||
1546 | rc = bfad_iocmd_diag_memtest(bfad, iocmd); | ||
1547 | break; | ||
1548 | case IOCMD_DIAG_LOOPBACK: | ||
1549 | rc = bfad_iocmd_diag_loopback(bfad, iocmd); | ||
1550 | break; | ||
1551 | case IOCMD_DIAG_FWPING: | ||
1552 | rc = bfad_iocmd_diag_fwping(bfad, iocmd); | ||
1553 | break; | ||
1554 | case IOCMD_DIAG_QUEUETEST: | ||
1555 | rc = bfad_iocmd_diag_queuetest(bfad, iocmd); | ||
1556 | break; | ||
1557 | case IOCMD_DIAG_SFP: | ||
1558 | rc = bfad_iocmd_diag_sfp(bfad, iocmd); | ||
1559 | break; | ||
1560 | case IOCMD_DIAG_LED: | ||
1561 | rc = bfad_iocmd_diag_led(bfad, iocmd); | ||
1562 | break; | ||
1563 | case IOCMD_DIAG_BEACON_LPORT: | ||
1564 | rc = bfad_iocmd_diag_beacon_lport(bfad, iocmd); | ||
1565 | break; | ||
1566 | case IOCMD_DIAG_LB_STAT: | ||
1567 | rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); | ||
1568 | break; | ||
1363 | default: | 1569 | default: |
1364 | rc = EINVAL; | 1570 | rc = EINVAL; |
1365 | break; | 1571 | break; |
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 6bece6c1d876..89942773febe 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h | |||
@@ -71,6 +71,15 @@ enum { | |||
71 | IOCMD_FLASH_ERASE_PART, | 71 | IOCMD_FLASH_ERASE_PART, |
72 | IOCMD_FLASH_UPDATE_PART, | 72 | IOCMD_FLASH_UPDATE_PART, |
73 | IOCMD_FLASH_READ_PART, | 73 | IOCMD_FLASH_READ_PART, |
74 | IOCMD_DIAG_TEMP, | ||
75 | IOCMD_DIAG_MEMTEST, | ||
76 | IOCMD_DIAG_LOOPBACK, | ||
77 | IOCMD_DIAG_FWPING, | ||
78 | IOCMD_DIAG_QUEUETEST, | ||
79 | IOCMD_DIAG_SFP, | ||
80 | IOCMD_DIAG_LED, | ||
81 | IOCMD_DIAG_BEACON_LPORT, | ||
82 | IOCMD_DIAG_LB_STAT, | ||
74 | }; | 83 | }; |
75 | 84 | ||
76 | struct bfa_bsg_gen_s { | 85 | struct bfa_bsg_gen_s { |
@@ -357,6 +366,80 @@ struct bfa_bsg_flash_s { | |||
357 | u64 buf_ptr; | 366 | u64 buf_ptr; |
358 | }; | 367 | }; |
359 | 368 | ||
369 | struct bfa_bsg_diag_get_temp_s { | ||
370 | bfa_status_t status; | ||
371 | u16 bfad_num; | ||
372 | u16 rsvd; | ||
373 | struct bfa_diag_results_tempsensor_s result; | ||
374 | }; | ||
375 | |||
376 | struct bfa_bsg_diag_memtest_s { | ||
377 | bfa_status_t status; | ||
378 | u16 bfad_num; | ||
379 | u16 rsvd[3]; | ||
380 | u32 pat; | ||
381 | struct bfa_diag_memtest_result result; | ||
382 | struct bfa_diag_memtest_s memtest; | ||
383 | }; | ||
384 | |||
385 | struct bfa_bsg_diag_loopback_s { | ||
386 | bfa_status_t status; | ||
387 | u16 bfad_num; | ||
388 | u16 rsvd; | ||
389 | enum bfa_port_opmode opmode; | ||
390 | enum bfa_port_speed speed; | ||
391 | u32 lpcnt; | ||
392 | u32 pat; | ||
393 | struct bfa_diag_loopback_result_s result; | ||
394 | }; | ||
395 | |||
396 | struct bfa_bsg_diag_fwping_s { | ||
397 | bfa_status_t status; | ||
398 | u16 bfad_num; | ||
399 | u16 rsvd; | ||
400 | u32 cnt; | ||
401 | u32 pattern; | ||
402 | struct bfa_diag_results_fwping result; | ||
403 | }; | ||
404 | |||
405 | struct bfa_bsg_diag_qtest_s { | ||
406 | bfa_status_t status; | ||
407 | u16 bfad_num; | ||
408 | u16 rsvd; | ||
409 | u32 force; | ||
410 | u32 queue; | ||
411 | struct bfa_diag_qtest_result_s result; | ||
412 | }; | ||
413 | |||
414 | struct bfa_bsg_sfp_show_s { | ||
415 | bfa_status_t status; | ||
416 | u16 bfad_num; | ||
417 | u16 rsvd; | ||
418 | struct sfp_mem_s sfp; | ||
419 | }; | ||
420 | |||
421 | struct bfa_bsg_diag_led_s { | ||
422 | bfa_status_t status; | ||
423 | u16 bfad_num; | ||
424 | u16 rsvd; | ||
425 | struct bfa_diag_ledtest_s ledtest; | ||
426 | }; | ||
427 | |||
428 | struct bfa_bsg_diag_beacon_s { | ||
429 | bfa_status_t status; | ||
430 | u16 bfad_num; | ||
431 | u16 rsvd; | ||
432 | bfa_boolean_t beacon; | ||
433 | bfa_boolean_t link_e2e_beacon; | ||
434 | u32 second; | ||
435 | }; | ||
436 | |||
437 | struct bfa_bsg_diag_lb_stat_s { | ||
438 | bfa_status_t status; | ||
439 | u16 bfad_num; | ||
440 | u16 rsvd; | ||
441 | }; | ||
442 | |||
360 | struct bfa_bsg_fcpt_s { | 443 | struct bfa_bsg_fcpt_s { |
361 | bfa_status_t status; | 444 | bfa_status_t status; |
362 | u16 vf_id; | 445 | u16 vf_id; |
diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c index 48be0c54f2de..b412e0300dd4 100644 --- a/drivers/scsi/bfa/bfad_debugfs.c +++ b/drivers/scsi/bfa/bfad_debugfs.c | |||
@@ -214,10 +214,10 @@ bfad_debugfs_read(struct file *file, char __user *buf, | |||
214 | 214 | ||
215 | #define BFA_REG_CT_ADDRSZ (0x40000) | 215 | #define BFA_REG_CT_ADDRSZ (0x40000) |
216 | #define BFA_REG_CB_ADDRSZ (0x20000) | 216 | #define BFA_REG_CB_ADDRSZ (0x20000) |
217 | #define BFA_REG_ADDRSZ(__bfa) \ | 217 | #define BFA_REG_ADDRSZ(__ioc) \ |
218 | ((bfa_ioc_devid(&(__bfa)->ioc) == BFA_PCI_DEVICE_ID_CT) ? \ | 218 | ((u32)(bfa_asic_id_ctc(bfa_ioc_devid(__ioc)) ? \ |
219 | BFA_REG_CT_ADDRSZ : BFA_REG_CB_ADDRSZ) | 219 | BFA_REG_CT_ADDRSZ : BFA_REG_CB_ADDRSZ)) |
220 | #define BFA_REG_ADDRMSK(__bfa) ((u32)(BFA_REG_ADDRSZ(__bfa) - 1)) | 220 | #define BFA_REG_ADDRMSK(__ioc) (BFA_REG_ADDRSZ(__ioc) - 1) |
221 | 221 | ||
222 | static bfa_status_t | 222 | static bfa_status_t |
223 | bfad_reg_offset_check(struct bfa_s *bfa, u32 offset, u32 len) | 223 | bfad_reg_offset_check(struct bfa_s *bfa, u32 offset, u32 len) |
@@ -236,7 +236,7 @@ bfad_reg_offset_check(struct bfa_s *bfa, u32 offset, u32 len) | |||
236 | return BFA_STATUS_EINVAL; | 236 | return BFA_STATUS_EINVAL; |
237 | } else { | 237 | } else { |
238 | /* CB register space 64KB */ | 238 | /* CB register space 64KB */ |
239 | if ((offset + (len<<2)) > BFA_REG_ADDRMSK(bfa)) | 239 | if ((offset + (len<<2)) > BFA_REG_ADDRMSK(&bfa->ioc)) |
240 | return BFA_STATUS_EINVAL; | 240 | return BFA_STATUS_EINVAL; |
241 | } | 241 | } |
242 | return BFA_STATUS_OK; | 242 | return BFA_STATUS_OK; |
@@ -317,7 +317,7 @@ bfad_debugfs_write_regrd(struct file *file, const char __user *buf, | |||
317 | 317 | ||
318 | bfad->reglen = len << 2; | 318 | bfad->reglen = len << 2; |
319 | rb = bfa_ioc_bar0(ioc); | 319 | rb = bfa_ioc_bar0(ioc); |
320 | addr &= BFA_REG_ADDRMSK(bfa); | 320 | addr &= BFA_REG_ADDRMSK(ioc); |
321 | 321 | ||
322 | /* offset and len sanity check */ | 322 | /* offset and len sanity check */ |
323 | rc = bfad_reg_offset_check(bfa, addr, len); | 323 | rc = bfad_reg_offset_check(bfa, addr, len); |
@@ -380,7 +380,7 @@ bfad_debugfs_write_regwr(struct file *file, const char __user *buf, | |||
380 | } | 380 | } |
381 | kfree(kern_buf); | 381 | kfree(kern_buf); |
382 | 382 | ||
383 | addr &= BFA_REG_ADDRMSK(bfa); /* offset only 17 bit and word align */ | 383 | addr &= BFA_REG_ADDRMSK(ioc); /* offset only 17 bit and word align */ |
384 | 384 | ||
385 | /* offset and len sanity check */ | 385 | /* offset and len sanity check */ |
386 | rc = bfad_reg_offset_check(bfa, addr, 1); | 386 | rc = bfad_reg_offset_check(bfa, addr, 1); |
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index b7eb3dc27d5b..efa41b64bb32 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h | |||
@@ -190,6 +190,7 @@ enum bfi_pcifn_class { | |||
190 | */ | 190 | */ |
191 | enum bfi_mclass { | 191 | enum bfi_mclass { |
192 | BFI_MC_IOC = 1, /* IO Controller (IOC) */ | 192 | BFI_MC_IOC = 1, /* IO Controller (IOC) */ |
193 | BFI_MC_DIAG = 2, /* Diagnostic Msgs */ | ||
193 | BFI_MC_FLASH = 3, /* Flash message class */ | 194 | BFI_MC_FLASH = 3, /* Flash message class */ |
194 | BFI_MC_CEE = 4, /* CEE */ | 195 | BFI_MC_CEE = 4, /* CEE */ |
195 | BFI_MC_FCPORT = 5, /* FC port */ | 196 | BFI_MC_FCPORT = 5, /* FC port */ |
@@ -339,7 +340,7 @@ struct bfi_ioc_image_hdr_s { | |||
339 | ((u32)(__p1_mode))) | 340 | ((u32)(__p1_mode))) |
340 | 341 | ||
341 | #define BFI_FWBOOT_TYPE_NORMAL 0 | 342 | #define BFI_FWBOOT_TYPE_NORMAL 0 |
342 | #define BFI_FWBOOT_TYPE_MEMTEST 1 | 343 | #define BFI_FWBOOT_TYPE_MEMTEST 2 |
343 | #define BFI_FWBOOT_ENV_OS 0 | 344 | #define BFI_FWBOOT_ENV_OS 0 |
344 | 345 | ||
345 | enum bfi_port_mode { | 346 | enum bfi_port_mode { |
@@ -923,6 +924,112 @@ struct bfi_flash_erase_rsp_s { | |||
923 | u32 status; | 924 | u32 status; |
924 | }; | 925 | }; |
925 | 926 | ||
927 | /* | ||
928 | *---------------------------------------------------------------------- | ||
929 | * DIAG | ||
930 | *---------------------------------------------------------------------- | ||
931 | */ | ||
932 | enum bfi_diag_h2i { | ||
933 | BFI_DIAG_H2I_PORTBEACON = 1, | ||
934 | BFI_DIAG_H2I_LOOPBACK = 2, | ||
935 | BFI_DIAG_H2I_FWPING = 3, | ||
936 | BFI_DIAG_H2I_TEMPSENSOR = 4, | ||
937 | BFI_DIAG_H2I_LEDTEST = 5, | ||
938 | BFI_DIAG_H2I_QTEST = 6, | ||
939 | }; | ||
940 | |||
941 | enum bfi_diag_i2h { | ||
942 | BFI_DIAG_I2H_PORTBEACON = BFA_I2HM(BFI_DIAG_H2I_PORTBEACON), | ||
943 | BFI_DIAG_I2H_LOOPBACK = BFA_I2HM(BFI_DIAG_H2I_LOOPBACK), | ||
944 | BFI_DIAG_I2H_FWPING = BFA_I2HM(BFI_DIAG_H2I_FWPING), | ||
945 | BFI_DIAG_I2H_TEMPSENSOR = BFA_I2HM(BFI_DIAG_H2I_TEMPSENSOR), | ||
946 | BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST), | ||
947 | BFI_DIAG_I2H_QTEST = BFA_I2HM(BFI_DIAG_H2I_QTEST), | ||
948 | }; | ||
949 | |||
950 | #define BFI_DIAG_MAX_SGES 2 | ||
951 | #define BFI_DIAG_DMA_BUF_SZ (2 * 1024) | ||
952 | #define BFI_BOOT_MEMTEST_RES_ADDR 0x900 | ||
953 | #define BFI_BOOT_MEMTEST_RES_SIG 0xA0A1A2A3 | ||
954 | |||
955 | struct bfi_diag_lb_req_s { | ||
956 | struct bfi_mhdr_s mh; | ||
957 | u32 loopcnt; | ||
958 | u32 pattern; | ||
959 | u8 lb_mode; /*!< bfa_port_opmode_t */ | ||
960 | u8 speed; /*!< bfa_port_speed_t */ | ||
961 | u8 rsvd[2]; | ||
962 | }; | ||
963 | |||
964 | struct bfi_diag_lb_rsp_s { | ||
965 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
966 | struct bfa_diag_loopback_result_s res; /* 16 bytes */ | ||
967 | }; | ||
968 | |||
969 | struct bfi_diag_fwping_req_s { | ||
970 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
971 | struct bfi_alen_s alen; /* 12 bytes */ | ||
972 | u32 data; /* user input data pattern */ | ||
973 | u32 count; /* user input dma count */ | ||
974 | u8 qtag; /* track CPE vc */ | ||
975 | u8 rsv[3]; | ||
976 | }; | ||
977 | |||
978 | struct bfi_diag_fwping_rsp_s { | ||
979 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
980 | u32 data; /* user input data pattern */ | ||
981 | u8 qtag; /* track CPE vc */ | ||
982 | u8 dma_status; /* dma status */ | ||
983 | u8 rsv[2]; | ||
984 | }; | ||
985 | |||
986 | /* | ||
987 | * Temperature Sensor | ||
988 | */ | ||
989 | struct bfi_diag_ts_req_s { | ||
990 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
991 | u16 temp; /* 10-bit A/D value */ | ||
992 | u16 brd_temp; /* 9-bit board temp */ | ||
993 | u8 status; | ||
994 | u8 ts_junc; /* show junction tempsensor */ | ||
995 | u8 ts_brd; /* show board tempsensor */ | ||
996 | u8 rsv; | ||
997 | }; | ||
998 | #define bfi_diag_ts_rsp_t struct bfi_diag_ts_req_s | ||
999 | |||
1000 | struct bfi_diag_ledtest_req_s { | ||
1001 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
1002 | u8 cmd; | ||
1003 | u8 color; | ||
1004 | u8 portid; | ||
1005 | u8 led; /* bitmap of LEDs to be tested */ | ||
1006 | u16 freq; /* no. of blinks every 10 secs */ | ||
1007 | u8 rsv[2]; | ||
1008 | }; | ||
1009 | |||
1010 | /* notify host led operation is done */ | ||
1011 | struct bfi_diag_ledtest_rsp_s { | ||
1012 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
1013 | }; | ||
1014 | |||
1015 | struct bfi_diag_portbeacon_req_s { | ||
1016 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
1017 | u32 period; /* beaconing period */ | ||
1018 | u8 beacon; /* 1: beacon on */ | ||
1019 | u8 rsvd[3]; | ||
1020 | }; | ||
1021 | |||
1022 | /* notify host the beacon is off */ | ||
1023 | struct bfi_diag_portbeacon_rsp_s { | ||
1024 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
1025 | }; | ||
1026 | |||
1027 | struct bfi_diag_qtest_req_s { | ||
1028 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
1029 | u32 data[BFI_LMSG_PL_WSZ]; /* fill up tcm prefetch area */ | ||
1030 | }; | ||
1031 | #define bfi_diag_qtest_rsp_t struct bfi_diag_qtest_req_s | ||
1032 | |||
926 | #pragma pack() | 1033 | #pragma pack() |
927 | 1034 | ||
928 | #endif /* __BFI_H__ */ | 1035 | #endif /* __BFI_H__ */ |