diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2012-09-21 17:23:59 -0700 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-10-07 11:03:50 +0100 |
commit | bc0e2c2a97c1747ac0ade9b8620b14079e69fe3d (patch) | |
tree | 41fa46fba9a056b22f3b1212e076ec33529cab15 /drivers/scsi/bfa/bfad_bsg.c | |
parent | 56d92aa5cf7c96c70f81d0350c94faf46a9fb76d (diff) | |
download | linux-bc0e2c2a97c1747ac0ade9b8620b14079e69fe3d.tar.bz2 |
[SCSI] bfa: Add support for FC Arbitrated Loop topology.
- Add private loop topology support at 2G/4G/8G speeds with following
limitations
1. No support for multiple initiators in the loop
2. No public loop support. If attached to a loop with an FL_Port,
device continues to work as a private NL_Port in the loop
3. No auto topology detection. User has to manually set the
configured topology to loop if attaching to loop.
- When loop topology is configured, enabling FC port features
QoS/Trunk/TRL are not allowed and vice versa.
Signed-off-by: Vijaya Mohan Guvva <vmohan@brocade.com>
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfad_bsg.c')
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.c | 112 |
1 files changed, 77 insertions, 35 deletions
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 0afa39076cef..8ddd7e8be977 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -888,16 +888,22 @@ bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd) spin_lock_irqsave(&bfad->bfad_lock, flags); - if (cmd == IOCMD_RATELIM_ENABLE) - fcport->cfg.ratelimit = BFA_TRUE; - else if (cmd == IOCMD_RATELIM_DISABLE) - fcport->cfg.ratelimit = BFA_FALSE; + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; + else { + if (cmd == IOCMD_RATELIM_ENABLE) + fcport->cfg.ratelimit = BFA_TRUE; + else if (cmd == IOCMD_RATELIM_DISABLE) + fcport->cfg.ratelimit = BFA_FALSE; - if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN) - fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS; + if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN) + fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS; + + iocmd->status = BFA_STATUS_OK; + } spin_unlock_irqrestore(&bfad->bfad_lock, flags); - iocmd->status = BFA_STATUS_OK; return 0; } @@ -919,8 +925,13 @@ bfad_iocmd_ratelim_speed(struct bfad_s *bfad, unsigned int cmd, void *pcmd) return 0; } - fcport->cfg.trl_def_speed = iocmd->speed; - iocmd->status = BFA_STATUS_OK; + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; + else { + fcport->cfg.trl_def_speed = iocmd->speed; + iocmd->status = BFA_STATUS_OK; + } spin_unlock_irqrestore(&bfad->bfad_lock, flags); return 0; @@ -2161,22 +2172,28 @@ bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) spin_lock_irqsave(&bfad->bfad_lock, flags); - if (v_cmd == IOCMD_TRUNK_ENABLE) { - trunk->attr.state = BFA_TRUNK_OFFLINE; - bfa_fcport_disable(&bfad->bfa); - fcport->cfg.trunked = BFA_TRUE; - } else if (v_cmd == IOCMD_TRUNK_DISABLE) { - trunk->attr.state = BFA_TRUNK_DISABLED; - bfa_fcport_disable(&bfad->bfa); - fcport->cfg.trunked = BFA_FALSE; - } + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; + else { + if (v_cmd == IOCMD_TRUNK_ENABLE) { + trunk->attr.state = BFA_TRUNK_OFFLINE; + bfa_fcport_disable(&bfad->bfa); + fcport->cfg.trunked = BFA_TRUE; + } else if (v_cmd == IOCMD_TRUNK_DISABLE) { + trunk->attr.state = BFA_TRUNK_DISABLED; + bfa_fcport_disable(&bfad->bfa); + fcport->cfg.trunked = BFA_FALSE; + } + + if (!bfa_fcport_is_disabled(&bfad->bfa)) + bfa_fcport_enable(&bfad->bfa); - if (!bfa_fcport_is_disabled(&bfad->bfa)) - bfa_fcport_enable(&bfad->bfa); + iocmd->status = BFA_STATUS_OK; + } spin_unlock_irqrestore(&bfad->bfad_lock, flags); - iocmd->status = BFA_STATUS_OK; return 0; } @@ -2189,12 +2206,17 @@ bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd) unsigned long flags; spin_lock_irqsave(&bfad->bfad_lock, flags); - memcpy((void *)&iocmd->attr, (void *)&trunk->attr, - sizeof(struct bfa_trunk_attr_s)); - iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa); + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; + else { + memcpy((void *)&iocmd->attr, (void *)&trunk->attr, + sizeof(struct bfa_trunk_attr_s)); + iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa); + iocmd->status = BFA_STATUS_OK; + } spin_unlock_irqrestore(&bfad->bfad_lock, flags); - iocmd->status = BFA_STATUS_OK; return 0; } @@ -2207,14 +2229,18 @@ bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) spin_lock_irqsave(&bfad->bfad_lock, flags); if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) { - if (v_cmd == IOCMD_QOS_ENABLE) - fcport->cfg.qos_enabled = BFA_TRUE; - else if (v_cmd == IOCMD_QOS_DISABLE) - fcport->cfg.qos_enabled = BFA_FALSE; + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; + else { + if (v_cmd == IOCMD_QOS_ENABLE) + fcport->cfg.qos_enabled = BFA_TRUE; + else if (v_cmd == IOCMD_QOS_DISABLE) + fcport->cfg.qos_enabled = BFA_FALSE; + } } spin_unlock_irqrestore(&bfad->bfad_lock, flags); - iocmd->status = BFA_STATUS_OK; return 0; } @@ -2226,11 +2252,17 @@ bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd) unsigned long flags; spin_lock_irqsave(&bfad->bfad_lock, flags); - iocmd->attr.state = fcport->qos_attr.state; - iocmd->attr.total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr); + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; + else { + iocmd->attr.state = fcport->qos_attr.state; + iocmd->attr.total_bb_cr = + be32_to_cpu(fcport->qos_attr.total_bb_cr); + iocmd->status = BFA_STATUS_OK; + } spin_unlock_irqrestore(&bfad->bfad_lock, flags); - iocmd->status = BFA_STATUS_OK; return 0; } @@ -2274,6 +2306,7 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd) struct bfad_hal_comp fcomp; unsigned long flags; struct bfa_cb_pending_q_s cb_qe; + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); init_completion(&fcomp.comp); bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, @@ -2281,7 +2314,11 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd) spin_lock_irqsave(&bfad->bfad_lock, flags); WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); - iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; + else + iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); spin_unlock_irqrestore(&bfad->bfad_lock, flags); if (iocmd->status != BFA_STATUS_OK) { bfa_trc(bfad, iocmd->status); @@ -2300,6 +2337,7 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd) struct bfad_hal_comp fcomp; unsigned long flags; struct bfa_cb_pending_q_s cb_qe; + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); init_completion(&fcomp.comp); bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, @@ -2307,7 +2345,11 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd) spin_lock_irqsave(&bfad->bfad_lock, flags); WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); - iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); + if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && + (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) + iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; + else + iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); spin_unlock_irqrestore(&bfad->bfad_lock, flags); if (iocmd->status != BFA_STATUS_OK) { bfa_trc(bfad, iocmd->status); |