diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-07-20 20:03:09 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-07-27 06:51:44 -0400 |
commit | 3ec4f2c8bff2568e5a51ba083db2c073321ca2c1 (patch) | |
tree | 95618b9afd2e59f6fa85c33603f34535e1b0485e /drivers/scsi | |
parent | 45191236b179877d259a40e13c5144628d4df37f (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.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.c | 10 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.c | 137 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.h | 20 |
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 | */ |
471 | enum bfa_qos_state { | 471 | enum 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 | ||
2231 | int | ||
2232 | bfad_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 | |||
2251 | int | ||
2252 | bfad_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 | |||
2267 | int | ||
2268 | bfad_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 | |||
2299 | int | ||
2300 | bfad_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; | ||
2322 | out: | ||
2323 | return 0; | ||
2324 | } | ||
2325 | |||
2326 | int | ||
2327 | bfad_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; | ||
2348 | out: | ||
2349 | return 0; | ||
2350 | } | ||
2351 | |||
2231 | static int | 2352 | static int |
2232 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | 2353 | bfad_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 | ||
134 | struct bfa_bsg_gen_s { | 140 | struct 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 | ||
675 | struct 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 | |||
682 | struct 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 | |||
669 | struct bfa_bsg_fcpt_s { | 689 | struct bfa_bsg_fcpt_s { |
670 | bfa_status_t status; | 690 | bfa_status_t status; |
671 | u16 vf_id; | 691 | u16 vf_id; |