aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2012-09-21 20:26:07 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-10-07 06:17:27 -0400
commite353546e447feb838db2d1b23bac23cb90755993 (patch)
treef2762c0aedd4bb0ef4ebdca889c782b180ecdddc /drivers/scsi/bfa
parent1306e31d417df05c25053c5632b26d1c1b22d1ed (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.h16
-rw-r--r--drivers/scsi/bfa/bfa_defs_svc.h1
-rw-r--r--drivers/scsi/bfa/bfa_port.c32
-rw-r--r--drivers/scsi/bfa/bfa_port.h3
-rw-r--r--drivers/scsi/bfa/bfa_svc.c505
-rw-r--r--drivers/scsi/bfa/bfa_svc.h19
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c56
-rw-r--r--drivers/scsi/bfa/bfad_bsg.h10
-rw-r--r--drivers/scsi/bfa/bfi.h19
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*/
519enum 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 */
511void
512bfa_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,
66u32 bfa_port_meminfo(void); 67u32 bfa_port_meminfo(void);
67void bfa_port_mem_claim(struct bfa_port_s *port, 68void bfa_port_mem_claim(struct bfa_port_s *port,
68 u8 *dma_kva, u64 dma_pa); 69 u8 *dma_kva, u64 dma_pa);
70void 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);
198static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, 200static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
199 enum bfa_fcport_sm_event event); 201 enum bfa_fcport_sm_event event);
202static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport,
203 enum bfa_fcport_sm_event event);
200 204
201static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, 205static 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
2698static void
2699bfa_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
3965bfa_boolean_t 4008bfa_boolean_t
4009bfa_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
4017bfa_boolean_t
3966bfa_fcport_is_ratelim(struct bfa_s *bfa) 4018bfa_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
4094void
4095bfa_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
4104void
4105bfa_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 */
5502enum 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
5510static void bfa_dport_sm_disabled(struct bfa_dport_s *dport,
5511 enum bfa_dport_sm_event event);
5512static void bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport,
5513 enum bfa_dport_sm_event event);
5514static void bfa_dport_sm_enabling(struct bfa_dport_s *dport,
5515 enum bfa_dport_sm_event event);
5516static void bfa_dport_sm_enabled(struct bfa_dport_s *dport,
5517 enum bfa_dport_sm_event event);
5518static void bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport,
5519 enum bfa_dport_sm_event event);
5520static void bfa_dport_sm_disabling(struct bfa_dport_s *dport,
5521 enum bfa_dport_sm_event event);
5522static void bfa_dport_qresume(void *cbarg);
5523static 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
5458static void 5568static void
5459bfa_fcdiag_iocdisable(struct bfa_s *bfa) 5569bfa_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
5471static void 5585static 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 */
5967static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport,
5968 enum bfi_dport_req req);
5969static void
5970bfa_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
5979static void
5980bfa_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
6006static void
6007bfa_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
6029static void
6030bfa_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
6049static void
6050bfa_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
6076static void
6077bfa_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
6099static void
6100bfa_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
6120static bfa_boolean_t
6121bfa_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
6153static void
6154bfa_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
6161static void
6162bfa_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 */
6173bfa_status_t
6174bfa_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 */
6263bfa_status_t
6264bfa_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
6317bfa_status_t
6318bfa_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);
552bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); 552bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
553bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa);
553enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); 554enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
554 555
555void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn); 556void 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);
564bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa); 565bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa);
565bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa); 566bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa);
567void bfa_fcport_dportenable(struct bfa_s *bfa);
568void bfa_fcport_dportdisable(struct bfa_s *bfa);
566bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa); 569bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa);
567void bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state); 570void 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
709struct 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
706struct bfa_fcdiag_s { 718struct 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);
725bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa); 738bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa);
739bfa_status_t bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn,
740 void *cbarg);
741bfa_status_t bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn,
742 void *cbarg);
743bfa_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
1749int 1749int
1750bfad_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
1781int
1782bfad_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
1795int
1750bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) 1796bfad_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
146struct bfa_bsg_gen_s { 149struct 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
619struct 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
616struct bfa_bsg_phy_attr_s { 626struct 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
965enum bfi_diag_i2h { 966enum 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 */
1062enum bfi_dport_req {
1063 BFI_DPORT_DISABLE = 0, /* disable dport request */
1064 BFI_DPORT_ENABLE = 1, /* enable dport request */
1065};
1066
1067struct 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 */
1060enum bfi_phy_h2i_msgs_e { 1079enum bfi_phy_h2i_msgs_e {