diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2012-09-21 20:26:07 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-10-07 06:17:27 -0400 |
commit | e353546e447feb838db2d1b23bac23cb90755993 (patch) | |
tree | f2762c0aedd4bb0ef4ebdca889c782b180ecdddc /drivers/scsi/bfa | |
parent | 1306e31d417df05c25053c5632b26d1c1b22d1ed (diff) |
[SCSI] bfa: Add diagnostic port (D-Port) support
- Introduced support for D-Port which is a new port mode during which
link level diagnostics can be run.
- Provided mechanism to dynamically configure D-Port and initiate diagnostic
tests to isolate any link level issues.
- In D-Port mode, the HBA port does not participate in fabric or login to the
remote device or run data traffic.
- Diagnostic tests include running various loopback tests in conjunction with
the attached device.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa')
-rw-r--r-- | drivers/scsi/bfa/bfa_defs.h | 16 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_defs_svc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_port.c | 32 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_port.h | 3 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.c | 505 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.h | 19 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.c | 56 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.h | 10 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi.h | 19 |
9 files changed, 658 insertions, 3 deletions
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index 4e7777682089..b4d5d87f54ff 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h | |||
@@ -165,6 +165,7 @@ enum bfa_status { | |||
165 | BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */ | 165 | BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */ |
166 | BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */ | 166 | BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */ |
167 | BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */ | 167 | BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */ |
168 | BFA_STATUS_CMD_NOTSUPP_CNA = 146, /* Command not supported for CNA */ | ||
168 | BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot | 169 | BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot |
169 | * configuration */ | 170 | * configuration */ |
170 | BFA_STATUS_BAD_FWCFG = 156, /* Bad firmware configuration */ | 171 | BFA_STATUS_BAD_FWCFG = 156, /* Bad firmware configuration */ |
@@ -189,6 +190,10 @@ enum bfa_status { | |||
189 | BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */ | 190 | BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */ |
190 | BFA_STATUS_LOOP_UNSUPP_MEZZ = 231, /* Loop topology is not supported | 191 | BFA_STATUS_LOOP_UNSUPP_MEZZ = 231, /* Loop topology is not supported |
191 | * on mezz cards */ | 192 | * on mezz cards */ |
193 | BFA_STATUS_DPORT_ENABLED = 235, /* D-port mode is already enabled */ | ||
194 | BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */ | ||
195 | BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */ | ||
196 | BFA_STATUS_DPORT_ERR = 245, /* D-port mode is enabled */ | ||
192 | BFA_STATUS_MAX_VAL /* Unknown error code */ | 197 | BFA_STATUS_MAX_VAL /* Unknown error code */ |
193 | }; | 198 | }; |
194 | #define bfa_status_t enum bfa_status | 199 | #define bfa_status_t enum bfa_status |
@@ -508,6 +513,17 @@ struct bfa_ioc_aen_data_s { | |||
508 | }; | 513 | }; |
509 | 514 | ||
510 | /* | 515 | /* |
516 | * D-port states | ||
517 | * | ||
518 | */ | ||
519 | enum bfa_dport_state { | ||
520 | BFA_DPORT_ST_DISABLED = 0, /* D-port is Disabled */ | ||
521 | BFA_DPORT_ST_DISABLING = 1, /* D-port is Disabling */ | ||
522 | BFA_DPORT_ST_ENABLING = 2, /* D-port is Enabling */ | ||
523 | BFA_DPORT_ST_ENABLED = 3, /* D-port is Enabled */ | ||
524 | }; | ||
525 | |||
526 | /* | ||
511 | * ---------------------- mfg definitions ------------ | 527 | * ---------------------- mfg definitions ------------ |
512 | */ | 528 | */ |
513 | 529 | ||
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index 20749f193381..4533b28a6799 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h | |||
@@ -722,6 +722,7 @@ enum bfa_port_states { | |||
722 | BFA_PORT_ST_PREBOOT_DISABLED = 13, | 722 | BFA_PORT_ST_PREBOOT_DISABLED = 13, |
723 | BFA_PORT_ST_TOGGLING_QWAIT = 14, | 723 | BFA_PORT_ST_TOGGLING_QWAIT = 14, |
724 | BFA_PORT_ST_ACQ_ADDR = 15, | 724 | BFA_PORT_ST_ACQ_ADDR = 15, |
725 | BFA_PORT_ST_DPORT = 16, | ||
725 | BFA_PORT_ST_MAX_STATE, | 726 | BFA_PORT_ST_MAX_STATE, |
726 | }; | 727 | }; |
727 | 728 | ||
diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c index 95e4ad8759ac..8ea7697deb9b 100644 --- a/drivers/scsi/bfa/bfa_port.c +++ b/drivers/scsi/bfa/bfa_port.c | |||
@@ -250,6 +250,12 @@ bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn, | |||
250 | return BFA_STATUS_IOC_FAILURE; | 250 | return BFA_STATUS_IOC_FAILURE; |
251 | } | 251 | } |
252 | 252 | ||
253 | /* if port is d-port enabled, return error */ | ||
254 | if (port->dport_enabled) { | ||
255 | bfa_trc(port, BFA_STATUS_DPORT_ERR); | ||
256 | return BFA_STATUS_DPORT_ERR; | ||
257 | } | ||
258 | |||
253 | if (port->endis_pending) { | 259 | if (port->endis_pending) { |
254 | bfa_trc(port, BFA_STATUS_DEVBUSY); | 260 | bfa_trc(port, BFA_STATUS_DEVBUSY); |
255 | return BFA_STATUS_DEVBUSY; | 261 | return BFA_STATUS_DEVBUSY; |
@@ -300,6 +306,12 @@ bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn, | |||
300 | return BFA_STATUS_IOC_FAILURE; | 306 | return BFA_STATUS_IOC_FAILURE; |
301 | } | 307 | } |
302 | 308 | ||
309 | /* if port is d-port enabled, return error */ | ||
310 | if (port->dport_enabled) { | ||
311 | bfa_trc(port, BFA_STATUS_DPORT_ERR); | ||
312 | return BFA_STATUS_DPORT_ERR; | ||
313 | } | ||
314 | |||
303 | if (port->endis_pending) { | 315 | if (port->endis_pending) { |
304 | bfa_trc(port, BFA_STATUS_DEVBUSY); | 316 | bfa_trc(port, BFA_STATUS_DEVBUSY); |
305 | return BFA_STATUS_DEVBUSY; | 317 | return BFA_STATUS_DEVBUSY; |
@@ -431,6 +443,10 @@ bfa_port_notify(void *arg, enum bfa_ioc_event_e event) | |||
431 | port->endis_cbfn = NULL; | 443 | port->endis_cbfn = NULL; |
432 | port->endis_pending = BFA_FALSE; | 444 | port->endis_pending = BFA_FALSE; |
433 | } | 445 | } |
446 | |||
447 | /* clear D-port mode */ | ||
448 | if (port->dport_enabled) | ||
449 | bfa_port_set_dportenabled(port, BFA_FALSE); | ||
434 | break; | 450 | break; |
435 | default: | 451 | default: |
436 | break; | 452 | break; |
@@ -467,6 +483,7 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, | |||
467 | port->stats_cbfn = NULL; | 483 | port->stats_cbfn = NULL; |
468 | port->endis_cbfn = NULL; | 484 | port->endis_cbfn = NULL; |
469 | port->pbc_disabled = BFA_FALSE; | 485 | port->pbc_disabled = BFA_FALSE; |
486 | port->dport_enabled = BFA_FALSE; | ||
470 | 487 | ||
471 | bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port); | 488 | bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port); |
472 | bfa_q_qe_init(&port->ioc_notify); | 489 | bfa_q_qe_init(&port->ioc_notify); |
@@ -483,6 +500,21 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, | |||
483 | } | 500 | } |
484 | 501 | ||
485 | /* | 502 | /* |
503 | * bfa_port_set_dportenabled(); | ||
504 | * | ||
505 | * Port module- set pbc disabled flag | ||
506 | * | ||
507 | * @param[in] port - Pointer to the Port module data structure | ||
508 | * | ||
509 | * @return void | ||
510 | */ | ||
511 | void | ||
512 | bfa_port_set_dportenabled(struct bfa_port_s *port, bfa_boolean_t enabled) | ||
513 | { | ||
514 | port->dport_enabled = enabled; | ||
515 | } | ||
516 | |||
517 | /* | ||
486 | * CEE module specific definitions | 518 | * CEE module specific definitions |
487 | */ | 519 | */ |
488 | 520 | ||
diff --git a/drivers/scsi/bfa/bfa_port.h b/drivers/scsi/bfa/bfa_port.h index 947f897328d6..2fcab6bc6280 100644 --- a/drivers/scsi/bfa/bfa_port.h +++ b/drivers/scsi/bfa/bfa_port.h | |||
@@ -45,6 +45,7 @@ struct bfa_port_s { | |||
45 | bfa_status_t endis_status; | 45 | bfa_status_t endis_status; |
46 | struct bfa_ioc_notify_s ioc_notify; | 46 | struct bfa_ioc_notify_s ioc_notify; |
47 | bfa_boolean_t pbc_disabled; | 47 | bfa_boolean_t pbc_disabled; |
48 | bfa_boolean_t dport_enabled; | ||
48 | struct bfa_mem_dma_s port_dma; | 49 | struct bfa_mem_dma_s port_dma; |
49 | }; | 50 | }; |
50 | 51 | ||
@@ -66,6 +67,8 @@ bfa_status_t bfa_port_disable(struct bfa_port_s *port, | |||
66 | u32 bfa_port_meminfo(void); | 67 | u32 bfa_port_meminfo(void); |
67 | void bfa_port_mem_claim(struct bfa_port_s *port, | 68 | void bfa_port_mem_claim(struct bfa_port_s *port, |
68 | u8 *dma_kva, u64 dma_pa); | 69 | u8 *dma_kva, u64 dma_pa); |
70 | void bfa_port_set_dportenabled(struct bfa_port_s *port, | ||
71 | bfa_boolean_t enabled); | ||
69 | 72 | ||
70 | /* | 73 | /* |
71 | * CEE declaration | 74 | * CEE declaration |
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index fcad11629f10..549bd45a7dbe 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c | |||
@@ -67,6 +67,8 @@ enum bfa_fcport_sm_event { | |||
67 | BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ | 67 | BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ |
68 | BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ | 68 | BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ |
69 | BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ | 69 | BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ |
70 | BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */ | ||
71 | BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */ | ||
70 | }; | 72 | }; |
71 | 73 | ||
72 | /* | 74 | /* |
@@ -197,6 +199,8 @@ static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, | |||
197 | enum bfa_fcport_sm_event event); | 199 | enum bfa_fcport_sm_event event); |
198 | static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, | 200 | static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, |
199 | enum bfa_fcport_sm_event event); | 201 | enum bfa_fcport_sm_event event); |
202 | static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, | ||
203 | enum bfa_fcport_sm_event event); | ||
200 | 204 | ||
201 | static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, | 205 | static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, |
202 | enum bfa_fcport_ln_sm_event event); | 206 | enum bfa_fcport_ln_sm_event event); |
@@ -226,6 +230,7 @@ static struct bfa_sm_table_s hal_port_sm_table[] = { | |||
226 | {BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED}, | 230 | {BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED}, |
227 | {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, | 231 | {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, |
228 | {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, | 232 | {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, |
233 | {BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT}, | ||
229 | }; | 234 | }; |
230 | 235 | ||
231 | 236 | ||
@@ -2606,6 +2611,10 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, | |||
2606 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); | 2611 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); |
2607 | break; | 2612 | break; |
2608 | 2613 | ||
2614 | case BFA_FCPORT_SM_DPORTENABLE: | ||
2615 | bfa_sm_set_state(fcport, bfa_fcport_sm_dport); | ||
2616 | break; | ||
2617 | |||
2609 | default: | 2618 | default: |
2610 | bfa_sm_fault(fcport->bfa, event); | 2619 | bfa_sm_fault(fcport->bfa, event); |
2611 | } | 2620 | } |
@@ -2686,6 +2695,38 @@ bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, | |||
2686 | } | 2695 | } |
2687 | } | 2696 | } |
2688 | 2697 | ||
2698 | static void | ||
2699 | bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event) | ||
2700 | { | ||
2701 | bfa_trc(fcport->bfa, event); | ||
2702 | |||
2703 | switch (event) { | ||
2704 | case BFA_FCPORT_SM_DPORTENABLE: | ||
2705 | case BFA_FCPORT_SM_DISABLE: | ||
2706 | case BFA_FCPORT_SM_ENABLE: | ||
2707 | case BFA_FCPORT_SM_START: | ||
2708 | /* | ||
2709 | * Ignore event for a port that is dport | ||
2710 | */ | ||
2711 | break; | ||
2712 | |||
2713 | case BFA_FCPORT_SM_STOP: | ||
2714 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); | ||
2715 | break; | ||
2716 | |||
2717 | case BFA_FCPORT_SM_HWFAIL: | ||
2718 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); | ||
2719 | break; | ||
2720 | |||
2721 | case BFA_FCPORT_SM_DPORTDISABLE: | ||
2722 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); | ||
2723 | break; | ||
2724 | |||
2725 | default: | ||
2726 | bfa_sm_fault(fcport->bfa, event); | ||
2727 | } | ||
2728 | } | ||
2729 | |||
2689 | /* | 2730 | /* |
2690 | * Link state is down | 2731 | * Link state is down |
2691 | */ | 2732 | */ |
@@ -3707,6 +3748,8 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology) | |||
3707 | return BFA_STATUS_UNSUPP_SPEED; | 3748 | return BFA_STATUS_UNSUPP_SPEED; |
3708 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) | 3749 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) |
3709 | return BFA_STATUS_LOOP_UNSUPP_MEZZ; | 3750 | return BFA_STATUS_LOOP_UNSUPP_MEZZ; |
3751 | if (bfa_fcport_is_dport(bfa) != BFA_FALSE) | ||
3752 | return BFA_STATUS_DPORT_ERR; | ||
3710 | break; | 3753 | break; |
3711 | 3754 | ||
3712 | case BFA_PORT_TOPOLOGY_AUTO: | 3755 | case BFA_PORT_TOPOLOGY_AUTO: |
@@ -3963,6 +4006,15 @@ bfa_fcport_is_disabled(struct bfa_s *bfa) | |||
3963 | } | 4006 | } |
3964 | 4007 | ||
3965 | bfa_boolean_t | 4008 | bfa_boolean_t |
4009 | bfa_fcport_is_dport(struct bfa_s *bfa) | ||
4010 | { | ||
4011 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | ||
4012 | |||
4013 | return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) == | ||
4014 | BFA_PORT_ST_DPORT); | ||
4015 | } | ||
4016 | |||
4017 | bfa_boolean_t | ||
3966 | bfa_fcport_is_ratelim(struct bfa_s *bfa) | 4018 | bfa_fcport_is_ratelim(struct bfa_s *bfa) |
3967 | { | 4019 | { |
3968 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | 4020 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
@@ -4039,6 +4091,26 @@ bfa_fcport_is_trunk_enabled(struct bfa_s *bfa) | |||
4039 | return fcport->cfg.trunked; | 4091 | return fcport->cfg.trunked; |
4040 | } | 4092 | } |
4041 | 4093 | ||
4094 | void | ||
4095 | bfa_fcport_dportenable(struct bfa_s *bfa) | ||
4096 | { | ||
4097 | /* | ||
4098 | * Assume caller check for port is in disable state | ||
4099 | */ | ||
4100 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTENABLE); | ||
4101 | bfa_port_set_dportenabled(&bfa->modules.port, BFA_TRUE); | ||
4102 | } | ||
4103 | |||
4104 | void | ||
4105 | bfa_fcport_dportdisable(struct bfa_s *bfa) | ||
4106 | { | ||
4107 | /* | ||
4108 | * Assume caller check for port is in disable state | ||
4109 | */ | ||
4110 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTDISABLE); | ||
4111 | bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE); | ||
4112 | } | ||
4113 | |||
4042 | /* | 4114 | /* |
4043 | * Rport State machine functions | 4115 | * Rport State machine functions |
4044 | */ | 4116 | */ |
@@ -5421,6 +5493,37 @@ bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw) | |||
5421 | } | 5493 | } |
5422 | 5494 | ||
5423 | /* | 5495 | /* |
5496 | * Dport forward declaration | ||
5497 | */ | ||
5498 | |||
5499 | /* | ||
5500 | * BFA DPORT state machine events | ||
5501 | */ | ||
5502 | enum bfa_dport_sm_event { | ||
5503 | BFA_DPORT_SM_ENABLE = 1, /* dport enable event */ | ||
5504 | BFA_DPORT_SM_DISABLE = 2, /* dport disable event */ | ||
5505 | BFA_DPORT_SM_FWRSP = 3, /* fw enable/disable rsp */ | ||
5506 | BFA_DPORT_SM_QRESUME = 4, /* CQ space available */ | ||
5507 | BFA_DPORT_SM_HWFAIL = 5, /* IOC h/w failure */ | ||
5508 | }; | ||
5509 | |||
5510 | static void bfa_dport_sm_disabled(struct bfa_dport_s *dport, | ||
5511 | enum bfa_dport_sm_event event); | ||
5512 | static void bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport, | ||
5513 | enum bfa_dport_sm_event event); | ||
5514 | static void bfa_dport_sm_enabling(struct bfa_dport_s *dport, | ||
5515 | enum bfa_dport_sm_event event); | ||
5516 | static void bfa_dport_sm_enabled(struct bfa_dport_s *dport, | ||
5517 | enum bfa_dport_sm_event event); | ||
5518 | static void bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport, | ||
5519 | enum bfa_dport_sm_event event); | ||
5520 | static void bfa_dport_sm_disabling(struct bfa_dport_s *dport, | ||
5521 | enum bfa_dport_sm_event event); | ||
5522 | static void bfa_dport_qresume(void *cbarg); | ||
5523 | static void bfa_dport_req_comp(struct bfa_dport_s *dport, | ||
5524 | bfi_diag_dport_rsp_t *msg); | ||
5525 | |||
5526 | /* | ||
5424 | * BFA fcdiag module | 5527 | * BFA fcdiag module |
5425 | */ | 5528 | */ |
5426 | #define BFA_DIAG_QTEST_TOV 1000 /* msec */ | 5529 | #define BFA_DIAG_QTEST_TOV 1000 /* msec */ |
@@ -5450,15 +5553,24 @@ bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
5450 | struct bfa_pcidev_s *pcidev) | 5553 | struct bfa_pcidev_s *pcidev) |
5451 | { | 5554 | { |
5452 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | 5555 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); |
5556 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
5557 | |||
5453 | fcdiag->bfa = bfa; | 5558 | fcdiag->bfa = bfa; |
5454 | fcdiag->trcmod = bfa->trcmod; | 5559 | fcdiag->trcmod = bfa->trcmod; |
5455 | /* The common DIAG attach bfa_diag_attach() will do all memory claim */ | 5560 | /* The common DIAG attach bfa_diag_attach() will do all memory claim */ |
5561 | dport->bfa = bfa; | ||
5562 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
5563 | bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport); | ||
5564 | dport->cbfn = NULL; | ||
5565 | dport->cbarg = NULL; | ||
5456 | } | 5566 | } |
5457 | 5567 | ||
5458 | static void | 5568 | static void |
5459 | bfa_fcdiag_iocdisable(struct bfa_s *bfa) | 5569 | bfa_fcdiag_iocdisable(struct bfa_s *bfa) |
5460 | { | 5570 | { |
5461 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | 5571 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); |
5572 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
5573 | |||
5462 | bfa_trc(fcdiag, fcdiag->lb.lock); | 5574 | bfa_trc(fcdiag, fcdiag->lb.lock); |
5463 | if (fcdiag->lb.lock) { | 5575 | if (fcdiag->lb.lock) { |
5464 | fcdiag->lb.status = BFA_STATUS_IOC_FAILURE; | 5576 | fcdiag->lb.status = BFA_STATUS_IOC_FAILURE; |
@@ -5466,6 +5578,8 @@ bfa_fcdiag_iocdisable(struct bfa_s *bfa) | |||
5466 | fcdiag->lb.lock = 0; | 5578 | fcdiag->lb.lock = 0; |
5467 | bfa_fcdiag_set_busy_status(fcdiag); | 5579 | bfa_fcdiag_set_busy_status(fcdiag); |
5468 | } | 5580 | } |
5581 | |||
5582 | bfa_sm_send_event(dport, BFA_DPORT_SM_HWFAIL); | ||
5469 | } | 5583 | } |
5470 | 5584 | ||
5471 | static void | 5585 | static void |
@@ -5650,6 +5764,9 @@ bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
5650 | case BFI_DIAG_I2H_QTEST: | 5764 | case BFI_DIAG_I2H_QTEST: |
5651 | bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); | 5765 | bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); |
5652 | break; | 5766 | break; |
5767 | case BFI_DIAG_I2H_DPORT: | ||
5768 | bfa_dport_req_comp(&fcdiag->dport, (bfi_diag_dport_rsp_t *)msg); | ||
5769 | break; | ||
5653 | default: | 5770 | default: |
5654 | bfa_trc(fcdiag, msg->mhdr.msg_id); | 5771 | bfa_trc(fcdiag, msg->mhdr.msg_id); |
5655 | WARN_ON(1); | 5772 | WARN_ON(1); |
@@ -5719,12 +5836,18 @@ bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode, | |||
5719 | } | 5836 | } |
5720 | } | 5837 | } |
5721 | 5838 | ||
5839 | /* | ||
5840 | * For CT2, 1G is not supported | ||
5841 | */ | ||
5842 | if ((speed == BFA_PORT_SPEED_1GBPS) && | ||
5843 | (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) { | ||
5844 | bfa_trc(fcdiag, speed); | ||
5845 | return BFA_STATUS_UNSUPP_SPEED; | ||
5846 | } | ||
5847 | |||
5722 | /* For Mezz card, port speed entered needs to be checked */ | 5848 | /* For Mezz card, port speed entered needs to be checked */ |
5723 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { | 5849 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { |
5724 | if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { | 5850 | if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { |
5725 | if ((speed == BFA_PORT_SPEED_1GBPS) && | ||
5726 | (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) | ||
5727 | return BFA_STATUS_UNSUPP_SPEED; | ||
5728 | if (!(speed == BFA_PORT_SPEED_1GBPS || | 5851 | if (!(speed == BFA_PORT_SPEED_1GBPS || |
5729 | speed == BFA_PORT_SPEED_2GBPS || | 5852 | speed == BFA_PORT_SPEED_2GBPS || |
5730 | speed == BFA_PORT_SPEED_4GBPS || | 5853 | speed == BFA_PORT_SPEED_4GBPS || |
@@ -5837,3 +5960,379 @@ bfa_fcdiag_lb_is_running(struct bfa_s *bfa) | |||
5837 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | 5960 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); |
5838 | return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK; | 5961 | return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK; |
5839 | } | 5962 | } |
5963 | |||
5964 | /* | ||
5965 | * D-port | ||
5966 | */ | ||
5967 | static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport, | ||
5968 | enum bfi_dport_req req); | ||
5969 | static void | ||
5970 | bfa_cb_fcdiag_dport(struct bfa_dport_s *dport, bfa_status_t bfa_status) | ||
5971 | { | ||
5972 | if (dport->cbfn != NULL) { | ||
5973 | dport->cbfn(dport->cbarg, bfa_status); | ||
5974 | dport->cbfn = NULL; | ||
5975 | dport->cbarg = NULL; | ||
5976 | } | ||
5977 | } | ||
5978 | |||
5979 | static void | ||
5980 | bfa_dport_sm_disabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
5981 | { | ||
5982 | bfa_trc(dport->bfa, event); | ||
5983 | |||
5984 | switch (event) { | ||
5985 | case BFA_DPORT_SM_ENABLE: | ||
5986 | bfa_fcport_dportenable(dport->bfa); | ||
5987 | if (bfa_dport_send_req(dport, BFI_DPORT_ENABLE)) | ||
5988 | bfa_sm_set_state(dport, bfa_dport_sm_enabling); | ||
5989 | else | ||
5990 | bfa_sm_set_state(dport, bfa_dport_sm_enabling_qwait); | ||
5991 | break; | ||
5992 | |||
5993 | case BFA_DPORT_SM_DISABLE: | ||
5994 | /* Already disabled */ | ||
5995 | break; | ||
5996 | |||
5997 | case BFA_DPORT_SM_HWFAIL: | ||
5998 | /* ignore */ | ||
5999 | break; | ||
6000 | |||
6001 | default: | ||
6002 | bfa_sm_fault(dport->bfa, event); | ||
6003 | } | ||
6004 | } | ||
6005 | |||
6006 | static void | ||
6007 | bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport, | ||
6008 | enum bfa_dport_sm_event event) | ||
6009 | { | ||
6010 | bfa_trc(dport->bfa, event); | ||
6011 | |||
6012 | switch (event) { | ||
6013 | case BFA_DPORT_SM_QRESUME: | ||
6014 | bfa_sm_set_state(dport, bfa_dport_sm_enabling); | ||
6015 | bfa_dport_send_req(dport, BFI_DPORT_ENABLE); | ||
6016 | break; | ||
6017 | |||
6018 | case BFA_DPORT_SM_HWFAIL: | ||
6019 | bfa_reqq_wcancel(&dport->reqq_wait); | ||
6020 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6021 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); | ||
6022 | break; | ||
6023 | |||
6024 | default: | ||
6025 | bfa_sm_fault(dport->bfa, event); | ||
6026 | } | ||
6027 | } | ||
6028 | |||
6029 | static void | ||
6030 | bfa_dport_sm_enabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
6031 | { | ||
6032 | bfa_trc(dport->bfa, event); | ||
6033 | |||
6034 | switch (event) { | ||
6035 | case BFA_DPORT_SM_FWRSP: | ||
6036 | bfa_sm_set_state(dport, bfa_dport_sm_enabled); | ||
6037 | break; | ||
6038 | |||
6039 | case BFA_DPORT_SM_HWFAIL: | ||
6040 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6041 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); | ||
6042 | break; | ||
6043 | |||
6044 | default: | ||
6045 | bfa_sm_fault(dport->bfa, event); | ||
6046 | } | ||
6047 | } | ||
6048 | |||
6049 | static void | ||
6050 | bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
6051 | { | ||
6052 | bfa_trc(dport->bfa, event); | ||
6053 | |||
6054 | switch (event) { | ||
6055 | case BFA_DPORT_SM_ENABLE: | ||
6056 | /* Already enabled */ | ||
6057 | break; | ||
6058 | |||
6059 | case BFA_DPORT_SM_DISABLE: | ||
6060 | bfa_fcport_dportdisable(dport->bfa); | ||
6061 | if (bfa_dport_send_req(dport, BFI_DPORT_DISABLE)) | ||
6062 | bfa_sm_set_state(dport, bfa_dport_sm_disabling); | ||
6063 | else | ||
6064 | bfa_sm_set_state(dport, bfa_dport_sm_disabling_qwait); | ||
6065 | break; | ||
6066 | |||
6067 | case BFA_DPORT_SM_HWFAIL: | ||
6068 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6069 | break; | ||
6070 | |||
6071 | default: | ||
6072 | bfa_sm_fault(dport->bfa, event); | ||
6073 | } | ||
6074 | } | ||
6075 | |||
6076 | static void | ||
6077 | bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport, | ||
6078 | enum bfa_dport_sm_event event) | ||
6079 | { | ||
6080 | bfa_trc(dport->bfa, event); | ||
6081 | |||
6082 | switch (event) { | ||
6083 | case BFA_DPORT_SM_QRESUME: | ||
6084 | bfa_sm_set_state(dport, bfa_dport_sm_disabling); | ||
6085 | bfa_dport_send_req(dport, BFI_DPORT_DISABLE); | ||
6086 | break; | ||
6087 | |||
6088 | case BFA_DPORT_SM_HWFAIL: | ||
6089 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6090 | bfa_reqq_wcancel(&dport->reqq_wait); | ||
6091 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); | ||
6092 | break; | ||
6093 | |||
6094 | default: | ||
6095 | bfa_sm_fault(dport->bfa, event); | ||
6096 | } | ||
6097 | } | ||
6098 | |||
6099 | static void | ||
6100 | bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
6101 | { | ||
6102 | bfa_trc(dport->bfa, event); | ||
6103 | |||
6104 | switch (event) { | ||
6105 | case BFA_DPORT_SM_FWRSP: | ||
6106 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6107 | break; | ||
6108 | |||
6109 | case BFA_DPORT_SM_HWFAIL: | ||
6110 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6111 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); | ||
6112 | break; | ||
6113 | |||
6114 | default: | ||
6115 | bfa_sm_fault(dport->bfa, event); | ||
6116 | } | ||
6117 | } | ||
6118 | |||
6119 | |||
6120 | static bfa_boolean_t | ||
6121 | bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req) | ||
6122 | { | ||
6123 | struct bfi_diag_dport_req_s *m; | ||
6124 | |||
6125 | /* | ||
6126 | * Increment message tag before queue check, so that responses to old | ||
6127 | * requests are discarded. | ||
6128 | */ | ||
6129 | dport->msgtag++; | ||
6130 | |||
6131 | /* | ||
6132 | * check for room in queue to send request now | ||
6133 | */ | ||
6134 | m = bfa_reqq_next(dport->bfa, BFA_REQQ_DIAG); | ||
6135 | if (!m) { | ||
6136 | bfa_reqq_wait(dport->bfa, BFA_REQQ_PORT, &dport->reqq_wait); | ||
6137 | return BFA_FALSE; | ||
6138 | } | ||
6139 | |||
6140 | bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT, | ||
6141 | bfa_fn_lpu(dport->bfa)); | ||
6142 | m->req = req; | ||
6143 | m->msgtag = dport->msgtag; | ||
6144 | |||
6145 | /* | ||
6146 | * queue I/O message to firmware | ||
6147 | */ | ||
6148 | bfa_reqq_produce(dport->bfa, BFA_REQQ_DIAG, m->mh); | ||
6149 | |||
6150 | return BFA_TRUE; | ||
6151 | } | ||
6152 | |||
6153 | static void | ||
6154 | bfa_dport_qresume(void *cbarg) | ||
6155 | { | ||
6156 | struct bfa_dport_s *dport = cbarg; | ||
6157 | |||
6158 | bfa_sm_send_event(dport, BFA_DPORT_SM_QRESUME); | ||
6159 | } | ||
6160 | |||
6161 | static void | ||
6162 | bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg) | ||
6163 | { | ||
6164 | bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP); | ||
6165 | bfa_cb_fcdiag_dport(dport, msg->status); | ||
6166 | } | ||
6167 | |||
6168 | /* | ||
6169 | * Dport enable | ||
6170 | * | ||
6171 | * @param[in] *bfa - bfa data struct | ||
6172 | */ | ||
6173 | bfa_status_t | ||
6174 | bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) | ||
6175 | { | ||
6176 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
6177 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
6178 | |||
6179 | /* | ||
6180 | * Dport is not support in MEZZ card | ||
6181 | */ | ||
6182 | if (bfa_mfg_is_mezz(dport->bfa->ioc.attr->card_type)) { | ||
6183 | bfa_trc(dport->bfa, BFA_STATUS_PBC); | ||
6184 | return BFA_STATUS_CMD_NOTSUPP_MEZZ; | ||
6185 | } | ||
6186 | |||
6187 | /* | ||
6188 | * Check to see if IOC is down | ||
6189 | */ | ||
6190 | if (!bfa_iocfc_is_operational(bfa)) | ||
6191 | return BFA_STATUS_IOC_NON_OP; | ||
6192 | |||
6193 | /* if port is PBC disabled, return error */ | ||
6194 | if (bfa_fcport_is_pbcdisabled(bfa)) { | ||
6195 | bfa_trc(dport->bfa, BFA_STATUS_PBC); | ||
6196 | return BFA_STATUS_PBC; | ||
6197 | } | ||
6198 | |||
6199 | /* | ||
6200 | * Check if port mode is FC port | ||
6201 | */ | ||
6202 | if (bfa_ioc_get_type(&bfa->ioc) != BFA_IOC_TYPE_FC) { | ||
6203 | bfa_trc(dport->bfa, bfa_ioc_get_type(&bfa->ioc)); | ||
6204 | return BFA_STATUS_CMD_NOTSUPP_CNA; | ||
6205 | } | ||
6206 | |||
6207 | /* | ||
6208 | * Check if port is in LOOP mode | ||
6209 | */ | ||
6210 | if ((bfa_fcport_get_cfg_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) || | ||
6211 | (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)) { | ||
6212 | bfa_trc(dport->bfa, 0); | ||
6213 | return BFA_STATUS_TOPOLOGY_LOOP; | ||
6214 | } | ||
6215 | |||
6216 | /* | ||
6217 | * Check if port is TRUNK mode | ||
6218 | */ | ||
6219 | if (bfa_fcport_is_trunk_enabled(bfa)) { | ||
6220 | bfa_trc(dport->bfa, 0); | ||
6221 | return BFA_STATUS_ERROR_TRUNK_ENABLED; | ||
6222 | } | ||
6223 | |||
6224 | /* | ||
6225 | * Check to see if port is disable or in dport state | ||
6226 | */ | ||
6227 | if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && | ||
6228 | (bfa_fcport_is_dport(bfa) == BFA_FALSE)) { | ||
6229 | bfa_trc(dport->bfa, 0); | ||
6230 | return BFA_STATUS_PORT_NOT_DISABLED; | ||
6231 | } | ||
6232 | |||
6233 | /* | ||
6234 | * Check if dport is busy | ||
6235 | */ | ||
6236 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || | ||
6237 | bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || | ||
6238 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || | ||
6239 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) { | ||
6240 | return BFA_STATUS_DEVBUSY; | ||
6241 | } | ||
6242 | |||
6243 | /* | ||
6244 | * Check if dport is already enabled | ||
6245 | */ | ||
6246 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) { | ||
6247 | bfa_trc(dport->bfa, 0); | ||
6248 | return BFA_STATUS_DPORT_ENABLED; | ||
6249 | } | ||
6250 | |||
6251 | dport->cbfn = cbfn; | ||
6252 | dport->cbarg = cbarg; | ||
6253 | |||
6254 | bfa_sm_send_event(dport, BFA_DPORT_SM_ENABLE); | ||
6255 | return BFA_STATUS_OK; | ||
6256 | } | ||
6257 | |||
6258 | /* | ||
6259 | * Dport disable | ||
6260 | * | ||
6261 | * @param[in] *bfa - bfa data struct | ||
6262 | */ | ||
6263 | bfa_status_t | ||
6264 | bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) | ||
6265 | { | ||
6266 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
6267 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
6268 | |||
6269 | if (bfa_ioc_is_disabled(&bfa->ioc)) | ||
6270 | return BFA_STATUS_IOC_DISABLED; | ||
6271 | |||
6272 | /* if port is PBC disabled, return error */ | ||
6273 | if (bfa_fcport_is_pbcdisabled(bfa)) { | ||
6274 | bfa_trc(dport->bfa, BFA_STATUS_PBC); | ||
6275 | return BFA_STATUS_PBC; | ||
6276 | } | ||
6277 | |||
6278 | /* | ||
6279 | * Check to see if port is disable or in dport state | ||
6280 | */ | ||
6281 | if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && | ||
6282 | (bfa_fcport_is_dport(bfa) == BFA_FALSE)) { | ||
6283 | bfa_trc(dport->bfa, 0); | ||
6284 | return BFA_STATUS_PORT_NOT_DISABLED; | ||
6285 | } | ||
6286 | |||
6287 | /* | ||
6288 | * Check if dport is busy | ||
6289 | */ | ||
6290 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || | ||
6291 | bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || | ||
6292 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || | ||
6293 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) | ||
6294 | return BFA_STATUS_DEVBUSY; | ||
6295 | |||
6296 | /* | ||
6297 | * Check if dport is already disabled | ||
6298 | */ | ||
6299 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) { | ||
6300 | bfa_trc(dport->bfa, 0); | ||
6301 | return BFA_STATUS_DPORT_DISABLED; | ||
6302 | } | ||
6303 | |||
6304 | dport->cbfn = cbfn; | ||
6305 | dport->cbarg = cbarg; | ||
6306 | |||
6307 | bfa_sm_send_event(dport, BFA_DPORT_SM_DISABLE); | ||
6308 | return BFA_STATUS_OK; | ||
6309 | } | ||
6310 | |||
6311 | /* | ||
6312 | * Get D-port state | ||
6313 | * | ||
6314 | * @param[in] *bfa - bfa data struct | ||
6315 | */ | ||
6316 | |||
6317 | bfa_status_t | ||
6318 | bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state) | ||
6319 | { | ||
6320 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
6321 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
6322 | |||
6323 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) | ||
6324 | *state = BFA_DPORT_ST_ENABLED; | ||
6325 | else if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || | ||
6326 | bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait)) | ||
6327 | *state = BFA_DPORT_ST_ENABLING; | ||
6328 | else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) | ||
6329 | *state = BFA_DPORT_ST_DISABLED; | ||
6330 | else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || | ||
6331 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) | ||
6332 | *state = BFA_DPORT_ST_DISABLING; | ||
6333 | else { | ||
6334 | bfa_trc(dport->bfa, BFA_STATUS_EINVAL); | ||
6335 | return BFA_STATUS_EINVAL; | ||
6336 | } | ||
6337 | return BFA_STATUS_OK; | ||
6338 | } | ||
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index 2d1cd4349bcd..1854ca3bc1a5 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h | |||
@@ -550,6 +550,7 @@ void bfa_fcport_event_register(struct bfa_s *bfa, | |||
550 | void (*event_cbfn) (void *cbarg, | 550 | void (*event_cbfn) (void *cbarg, |
551 | enum bfa_port_linkstate event), void *event_cbarg); | 551 | enum bfa_port_linkstate event), void *event_cbarg); |
552 | bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); | 552 | bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); |
553 | bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa); | ||
553 | enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); | 554 | enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); |
554 | 555 | ||
555 | void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn); | 556 | void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn); |
@@ -563,6 +564,8 @@ bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, | |||
563 | struct bfa_cb_pending_q_s *cb); | 564 | struct bfa_cb_pending_q_s *cb); |
564 | bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa); | 565 | bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa); |
565 | bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa); | 566 | bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa); |
567 | void bfa_fcport_dportenable(struct bfa_s *bfa); | ||
568 | void bfa_fcport_dportdisable(struct bfa_s *bfa); | ||
566 | bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa); | 569 | bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa); |
567 | void bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state); | 570 | void bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state); |
568 | 571 | ||
@@ -703,11 +706,21 @@ struct bfa_fcdiag_lb_s { | |||
703 | u32 status; | 706 | u32 status; |
704 | }; | 707 | }; |
705 | 708 | ||
709 | struct bfa_dport_s { | ||
710 | struct bfa_s *bfa; /* Back pointer to BFA */ | ||
711 | bfa_sm_t sm; /* finite state machine */ | ||
712 | u32 msgtag; /* firmware msg tag for reply */ | ||
713 | struct bfa_reqq_wait_s reqq_wait; | ||
714 | bfa_cb_diag_t cbfn; | ||
715 | void *cbarg; | ||
716 | }; | ||
717 | |||
706 | struct bfa_fcdiag_s { | 718 | struct bfa_fcdiag_s { |
707 | struct bfa_s *bfa; /* Back pointer to BFA */ | 719 | struct bfa_s *bfa; /* Back pointer to BFA */ |
708 | struct bfa_trc_mod_s *trcmod; | 720 | struct bfa_trc_mod_s *trcmod; |
709 | struct bfa_fcdiag_lb_s lb; | 721 | struct bfa_fcdiag_lb_s lb; |
710 | struct bfa_fcdiag_qtest_s qtest; | 722 | struct bfa_fcdiag_qtest_s qtest; |
723 | struct bfa_dport_s dport; | ||
711 | }; | 724 | }; |
712 | 725 | ||
713 | #define BFA_FCDIAG_MOD(__bfa) (&(__bfa)->modules.fcdiag) | 726 | #define BFA_FCDIAG_MOD(__bfa) (&(__bfa)->modules.fcdiag) |
@@ -723,5 +736,11 @@ bfa_status_t bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 ignore, | |||
723 | u32 queue, struct bfa_diag_qtest_result_s *result, | 736 | u32 queue, struct bfa_diag_qtest_result_s *result, |
724 | bfa_cb_diag_t cbfn, void *cbarg); | 737 | bfa_cb_diag_t cbfn, void *cbarg); |
725 | bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa); | 738 | bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa); |
739 | bfa_status_t bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, | ||
740 | void *cbarg); | ||
741 | bfa_status_t bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, | ||
742 | void *cbarg); | ||
743 | bfa_status_t bfa_dport_get_state(struct bfa_s *bfa, | ||
744 | enum bfa_dport_state *state); | ||
726 | 745 | ||
727 | #endif /* __BFA_SVC_H__ */ | 746 | #endif /* __BFA_SVC_H__ */ |
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 8ddd7e8be977..69b1ba9e58f6 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c | |||
@@ -1747,6 +1747,52 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) | |||
1747 | } | 1747 | } |
1748 | 1748 | ||
1749 | int | 1749 | int |
1750 | bfad_iocmd_diag_cfg_dport(struct bfad_s *bfad, unsigned int cmd, void *pcmd) | ||
1751 | { | ||
1752 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; | ||
1753 | unsigned long flags; | ||
1754 | struct bfad_hal_comp fcomp; | ||
1755 | |||
1756 | init_completion(&fcomp.comp); | ||
1757 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1758 | if (cmd == IOCMD_DIAG_DPORT_ENABLE) | ||
1759 | iocmd->status = bfa_dport_enable(&bfad->bfa, | ||
1760 | bfad_hcb_comp, &fcomp); | ||
1761 | else if (cmd == IOCMD_DIAG_DPORT_DISABLE) | ||
1762 | iocmd->status = bfa_dport_disable(&bfad->bfa, | ||
1763 | bfad_hcb_comp, &fcomp); | ||
1764 | else { | ||
1765 | bfa_trc(bfad, 0); | ||
1766 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1767 | return -EINVAL; | ||
1768 | } | ||
1769 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1770 | |||
1771 | if (iocmd->status != BFA_STATUS_OK) | ||
1772 | bfa_trc(bfad, iocmd->status); | ||
1773 | else { | ||
1774 | wait_for_completion(&fcomp.comp); | ||
1775 | iocmd->status = fcomp.status; | ||
1776 | } | ||
1777 | |||
1778 | return 0; | ||
1779 | } | ||
1780 | |||
1781 | int | ||
1782 | bfad_iocmd_diag_dport_get_state(struct bfad_s *bfad, void *pcmd) | ||
1783 | { | ||
1784 | struct bfa_bsg_diag_dport_get_state_s *iocmd = | ||
1785 | (struct bfa_bsg_diag_dport_get_state_s *)pcmd; | ||
1786 | unsigned long flags; | ||
1787 | |||
1788 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1789 | iocmd->status = bfa_dport_get_state(&bfad->bfa, &iocmd->state); | ||
1790 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1791 | |||
1792 | return 0; | ||
1793 | } | ||
1794 | |||
1795 | int | ||
1750 | bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) | 1796 | bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) |
1751 | { | 1797 | { |
1752 | struct bfa_bsg_phy_attr_s *iocmd = | 1798 | struct bfa_bsg_phy_attr_s *iocmd = |
@@ -2172,6 +2218,9 @@ bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) | |||
2172 | 2218 | ||
2173 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 2219 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2174 | 2220 | ||
2221 | if (bfa_fcport_is_dport(&bfad->bfa)) | ||
2222 | return BFA_STATUS_DPORT_ERR; | ||
2223 | |||
2175 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || | 2224 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || |
2176 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) | 2225 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
2177 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | 2226 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
@@ -2702,6 +2751,13 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | |||
2702 | case IOCMD_DIAG_LB_STAT: | 2751 | case IOCMD_DIAG_LB_STAT: |
2703 | rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); | 2752 | rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); |
2704 | break; | 2753 | break; |
2754 | case IOCMD_DIAG_DPORT_ENABLE: | ||
2755 | case IOCMD_DIAG_DPORT_DISABLE: | ||
2756 | rc = bfad_iocmd_diag_cfg_dport(bfad, cmd, iocmd); | ||
2757 | break; | ||
2758 | case IOCMD_DIAG_DPORT_GET_STATE: | ||
2759 | rc = bfad_iocmd_diag_dport_get_state(bfad, iocmd); | ||
2760 | break; | ||
2705 | case IOCMD_PHY_GET_ATTR: | 2761 | case IOCMD_PHY_GET_ATTR: |
2706 | rc = bfad_iocmd_phy_get_attr(bfad, iocmd); | 2762 | rc = bfad_iocmd_phy_get_attr(bfad, iocmd); |
2707 | break; | 2763 | break; |
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 8c569ddb750d..62f1b8809d19 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h | |||
@@ -141,6 +141,9 @@ enum { | |||
141 | IOCMD_FCPIM_LUNMASK_QUERY, | 141 | IOCMD_FCPIM_LUNMASK_QUERY, |
142 | IOCMD_FCPIM_LUNMASK_ADD, | 142 | IOCMD_FCPIM_LUNMASK_ADD, |
143 | IOCMD_FCPIM_LUNMASK_DELETE, | 143 | IOCMD_FCPIM_LUNMASK_DELETE, |
144 | IOCMD_DIAG_DPORT_ENABLE, | ||
145 | IOCMD_DIAG_DPORT_DISABLE, | ||
146 | IOCMD_DIAG_DPORT_GET_STATE, | ||
144 | }; | 147 | }; |
145 | 148 | ||
146 | struct bfa_bsg_gen_s { | 149 | struct bfa_bsg_gen_s { |
@@ -613,6 +616,13 @@ struct bfa_bsg_diag_lb_stat_s { | |||
613 | u16 rsvd; | 616 | u16 rsvd; |
614 | }; | 617 | }; |
615 | 618 | ||
619 | struct bfa_bsg_diag_dport_get_state_s { | ||
620 | bfa_status_t status; | ||
621 | u16 bfad_num; | ||
622 | u16 rsvd; | ||
623 | enum bfa_dport_state state; | ||
624 | }; | ||
625 | |||
616 | struct bfa_bsg_phy_attr_s { | 626 | struct bfa_bsg_phy_attr_s { |
617 | bfa_status_t status; | 627 | bfa_status_t status; |
618 | u16 bfad_num; | 628 | u16 bfad_num; |
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index e6269c28eaa2..6f1dd9eac1d1 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h | |||
@@ -960,6 +960,7 @@ enum bfi_diag_h2i { | |||
960 | BFI_DIAG_H2I_TEMPSENSOR = 4, | 960 | BFI_DIAG_H2I_TEMPSENSOR = 4, |
961 | BFI_DIAG_H2I_LEDTEST = 5, | 961 | BFI_DIAG_H2I_LEDTEST = 5, |
962 | BFI_DIAG_H2I_QTEST = 6, | 962 | BFI_DIAG_H2I_QTEST = 6, |
963 | BFI_DIAG_H2I_DPORT = 7, | ||
963 | }; | 964 | }; |
964 | 965 | ||
965 | enum bfi_diag_i2h { | 966 | enum bfi_diag_i2h { |
@@ -969,6 +970,7 @@ enum bfi_diag_i2h { | |||
969 | BFI_DIAG_I2H_TEMPSENSOR = BFA_I2HM(BFI_DIAG_H2I_TEMPSENSOR), | 970 | BFI_DIAG_I2H_TEMPSENSOR = BFA_I2HM(BFI_DIAG_H2I_TEMPSENSOR), |
970 | BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST), | 971 | BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST), |
971 | BFI_DIAG_I2H_QTEST = BFA_I2HM(BFI_DIAG_H2I_QTEST), | 972 | BFI_DIAG_I2H_QTEST = BFA_I2HM(BFI_DIAG_H2I_QTEST), |
973 | BFI_DIAG_I2H_DPORT = BFA_I2HM(BFI_DIAG_H2I_DPORT), | ||
972 | }; | 974 | }; |
973 | 975 | ||
974 | #define BFI_DIAG_MAX_SGES 2 | 976 | #define BFI_DIAG_MAX_SGES 2 |
@@ -1055,6 +1057,23 @@ struct bfi_diag_qtest_req_s { | |||
1055 | #define bfi_diag_qtest_rsp_t struct bfi_diag_qtest_req_s | 1057 | #define bfi_diag_qtest_rsp_t struct bfi_diag_qtest_req_s |
1056 | 1058 | ||
1057 | /* | 1059 | /* |
1060 | * D-port test | ||
1061 | */ | ||
1062 | enum bfi_dport_req { | ||
1063 | BFI_DPORT_DISABLE = 0, /* disable dport request */ | ||
1064 | BFI_DPORT_ENABLE = 1, /* enable dport request */ | ||
1065 | }; | ||
1066 | |||
1067 | struct bfi_diag_dport_req_s { | ||
1068 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
1069 | u8 req; /* request 1: enable 0: disable */ | ||
1070 | u8 status; /* reply status */ | ||
1071 | u8 rsvd[2]; | ||
1072 | u32 msgtag; /* msgtag for reply */ | ||
1073 | }; | ||
1074 | #define bfi_diag_dport_rsp_t struct bfi_diag_dport_req_s | ||
1075 | |||
1076 | /* | ||
1058 | * PHY module specific | 1077 | * PHY module specific |
1059 | */ | 1078 | */ |
1060 | enum bfi_phy_h2i_msgs_e { | 1079 | enum bfi_phy_h2i_msgs_e { |