aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2011-07-20 20:03:09 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-27 06:51:44 -0400
commit3ec4f2c8bff2568e5a51ba083db2c073321ca2c1 (patch)
tree95618b9afd2e59f6fa85c33603f34535e1b0485e /drivers/scsi
parent45191236b179877d259a40e13c5144628d4df37f (diff)
[SCSI] bfa: Added support to configure QOS and collect stats.
- Added support to configure QOS on Brocade adapter ports. - Added support to collect / reset QOS statistics. 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_defs_svc.h1
-rw-r--r--drivers/scsi/bfa/bfa_svc.c10
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c137
-rw-r--r--drivers/scsi/bfa/bfad_bsg.h20
4 files changed, 168 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h
index 21e3fbf0591b..263438bd8b6e 100644
--- a/drivers/scsi/bfa/bfa_defs_svc.h
+++ b/drivers/scsi/bfa/bfa_defs_svc.h
@@ -469,6 +469,7 @@ struct bfa_fw_stats_s {
469 * QoS states 469 * QoS states
470 */ 470 */
471enum bfa_qos_state { 471enum bfa_qos_state {
472 BFA_QOS_DISABLED = 0, /* QoS is disabled */
472 BFA_QOS_ONLINE = 1, /* QoS is online */ 473 BFA_QOS_ONLINE = 1, /* QoS is online */
473 BFA_QOS_OFFLINE = 2, /* QoS is offline */ 474 BFA_QOS_OFFLINE = 2, /* QoS is offline */
474}; 475};
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index 9884d6edfb57..d0ed4dd6f35a 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -2230,6 +2230,11 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
2230 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2230 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2231 "Base port online: WWN = %s\n", pwwn_buf); 2231 "Base port online: WWN = %s\n", pwwn_buf);
2232 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE); 2232 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
2233
2234 /* If QoS is enabled and it is not online, send AEN */
2235 if (fcport->cfg.qos_enabled &&
2236 fcport->qos_attr.state != BFA_QOS_ONLINE)
2237 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
2233 break; 2238 break;
2234 2239
2235 case BFA_FCPORT_SM_LINKDOWN: 2240 case BFA_FCPORT_SM_LINKDOWN:
@@ -3454,6 +3459,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
3454 fcport->use_flash_cfg = BFA_FALSE; 3459 fcport->use_flash_cfg = BFA_FALSE;
3455 } 3460 }
3456 3461
3462 if (fcport->cfg.qos_enabled)
3463 fcport->qos_attr.state = BFA_QOS_OFFLINE;
3464 else
3465 fcport->qos_attr.state = BFA_QOS_DISABLED;
3466
3457 bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); 3467 bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
3458 } 3468 }
3459 break; 3469 break;
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 55a9180b0a39..2109ed3769aa 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -2228,6 +2228,127 @@ bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd)
2228 return 0; 2228 return 0;
2229} 2229}
2230 2230
2231int
2232bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
2233{
2234 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
2235 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
2236 unsigned long flags;
2237
2238 spin_lock_irqsave(&bfad->bfad_lock, flags);
2239 if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) {
2240 if (v_cmd == IOCMD_QOS_ENABLE)
2241 fcport->cfg.qos_enabled = BFA_TRUE;
2242 else if (v_cmd == IOCMD_QOS_DISABLE)
2243 fcport->cfg.qos_enabled = BFA_FALSE;
2244 }
2245 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2246
2247 iocmd->status = BFA_STATUS_OK;
2248 return 0;
2249}
2250
2251int
2252bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd)
2253{
2254 struct bfa_bsg_qos_attr_s *iocmd = (struct bfa_bsg_qos_attr_s *)cmd;
2255 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
2256 unsigned long flags;
2257
2258 spin_lock_irqsave(&bfad->bfad_lock, flags);
2259 iocmd->attr.state = fcport->qos_attr.state;
2260 iocmd->attr.total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr);
2261 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2262
2263 iocmd->status = BFA_STATUS_OK;
2264 return 0;
2265}
2266
2267int
2268bfad_iocmd_qos_get_vc_attr(struct bfad_s *bfad, void *cmd)
2269{
2270 struct bfa_bsg_qos_vc_attr_s *iocmd =
2271 (struct bfa_bsg_qos_vc_attr_s *)cmd;
2272 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
2273 struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
2274 unsigned long flags;
2275 u32 i = 0;
2276
2277 spin_lock_irqsave(&bfad->bfad_lock, flags);
2278 iocmd->attr.total_vc_count = be16_to_cpu(bfa_vc_attr->total_vc_count);
2279 iocmd->attr.shared_credit = be16_to_cpu(bfa_vc_attr->shared_credit);
2280 iocmd->attr.elp_opmode_flags =
2281 be32_to_cpu(bfa_vc_attr->elp_opmode_flags);
2282
2283 /* Individual VC info */
2284 while (i < iocmd->attr.total_vc_count) {
2285 iocmd->attr.vc_info[i].vc_credit =
2286 bfa_vc_attr->vc_info[i].vc_credit;
2287 iocmd->attr.vc_info[i].borrow_credit =
2288 bfa_vc_attr->vc_info[i].borrow_credit;
2289 iocmd->attr.vc_info[i].priority =
2290 bfa_vc_attr->vc_info[i].priority;
2291 i++;
2292 }
2293 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2294
2295 iocmd->status = BFA_STATUS_OK;
2296 return 0;
2297}
2298
2299int
2300bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
2301{
2302 struct bfa_bsg_fcport_stats_s *iocmd =
2303 (struct bfa_bsg_fcport_stats_s *)cmd;
2304 struct bfad_hal_comp fcomp;
2305 unsigned long flags;
2306 struct bfa_cb_pending_q_s cb_qe;
2307
2308 init_completion(&fcomp.comp);
2309 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
2310 &fcomp, &iocmd->stats);
2311
2312 spin_lock_irqsave(&bfad->bfad_lock, flags);
2313 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
2314 iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
2315 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2316 if (iocmd->status != BFA_STATUS_OK) {
2317 bfa_trc(bfad, iocmd->status);
2318 goto out;
2319 }
2320 wait_for_completion(&fcomp.comp);
2321 iocmd->status = fcomp.status;
2322out:
2323 return 0;
2324}
2325
2326int
2327bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
2328{
2329 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
2330 struct bfad_hal_comp fcomp;
2331 unsigned long flags;
2332 struct bfa_cb_pending_q_s cb_qe;
2333
2334 init_completion(&fcomp.comp);
2335 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
2336 &fcomp, NULL);
2337
2338 spin_lock_irqsave(&bfad->bfad_lock, flags);
2339 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
2340 iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe);
2341 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2342 if (iocmd->status != BFA_STATUS_OK) {
2343 bfa_trc(bfad, iocmd->status);
2344 goto out;
2345 }
2346 wait_for_completion(&fcomp.comp);
2347 iocmd->status = fcomp.status;
2348out:
2349 return 0;
2350}
2351
2231static int 2352static int
2232bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, 2353bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
2233 unsigned int payload_len) 2354 unsigned int payload_len)
@@ -2524,6 +2645,22 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
2524 case IOCMD_TRUNK_GET_ATTR: 2645 case IOCMD_TRUNK_GET_ATTR:
2525 rc = bfad_iocmd_trunk_get_attr(bfad, iocmd); 2646 rc = bfad_iocmd_trunk_get_attr(bfad, iocmd);
2526 break; 2647 break;
2648 case IOCMD_QOS_ENABLE:
2649 case IOCMD_QOS_DISABLE:
2650 rc = bfad_iocmd_qos(bfad, iocmd, cmd);
2651 break;
2652 case IOCMD_QOS_GET_ATTR:
2653 rc = bfad_iocmd_qos_get_attr(bfad, iocmd);
2654 break;
2655 case IOCMD_QOS_GET_VC_ATTR:
2656 rc = bfad_iocmd_qos_get_vc_attr(bfad, iocmd);
2657 break;
2658 case IOCMD_QOS_GET_STATS:
2659 rc = bfad_iocmd_qos_get_stats(bfad, iocmd);
2660 break;
2661 case IOCMD_QOS_RESET_STATS:
2662 rc = bfad_iocmd_qos_reset_stats(bfad, iocmd);
2663 break;
2527 default: 2664 default:
2528 rc = -EINVAL; 2665 rc = -EINVAL;
2529 break; 2666 break;
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h
index 22680452ee1b..3c0ce22ed47e 100644
--- a/drivers/scsi/bfa/bfad_bsg.h
+++ b/drivers/scsi/bfa/bfad_bsg.h
@@ -129,6 +129,12 @@ enum {
129 IOCMD_TRUNK_ENABLE, 129 IOCMD_TRUNK_ENABLE,
130 IOCMD_TRUNK_DISABLE, 130 IOCMD_TRUNK_DISABLE,
131 IOCMD_TRUNK_GET_ATTR, 131 IOCMD_TRUNK_GET_ATTR,
132 IOCMD_QOS_ENABLE,
133 IOCMD_QOS_DISABLE,
134 IOCMD_QOS_GET_ATTR,
135 IOCMD_QOS_GET_VC_ATTR,
136 IOCMD_QOS_GET_STATS,
137 IOCMD_QOS_RESET_STATS,
132}; 138};
133 139
134struct bfa_bsg_gen_s { 140struct bfa_bsg_gen_s {
@@ -666,6 +672,20 @@ struct bfa_bsg_trunk_attr_s {
666 struct bfa_trunk_attr_s attr; 672 struct bfa_trunk_attr_s attr;
667}; 673};
668 674
675struct bfa_bsg_qos_attr_s {
676 bfa_status_t status;
677 u16 bfad_num;
678 u16 rsvd;
679 struct bfa_qos_attr_s attr;
680};
681
682struct bfa_bsg_qos_vc_attr_s {
683 bfa_status_t status;
684 u16 bfad_num;
685 u16 rsvd;
686 struct bfa_qos_vc_attr_s attr;
687};
688
669struct bfa_bsg_fcpt_s { 689struct bfa_bsg_fcpt_s {
670 bfa_status_t status; 690 bfa_status_t status;
671 u16 vf_id; 691 u16 vf_id;