[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>
This commit is contained in:
Krishna Gudipati 2011-07-20 17:03:09 -07:00 коммит произвёл James Bottomley
Родитель 45191236b1
Коммит 3ec4f2c8bf
4 изменённых файлов: 168 добавлений и 0 удалений

Просмотреть файл

@ -469,6 +469,7 @@ struct bfa_fw_stats_s {
* QoS states
*/
enum bfa_qos_state {
BFA_QOS_DISABLED = 0, /* QoS is disabled */
BFA_QOS_ONLINE = 1, /* QoS is online */
BFA_QOS_OFFLINE = 2, /* QoS is offline */
};

Просмотреть файл

@ -2230,6 +2230,11 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
"Base port online: WWN = %s\n", pwwn_buf);
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
/* If QoS is enabled and it is not online, send AEN */
if (fcport->cfg.qos_enabled &&
fcport->qos_attr.state != BFA_QOS_ONLINE)
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
break;
case BFA_FCPORT_SM_LINKDOWN:
@ -3454,6 +3459,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
fcport->use_flash_cfg = BFA_FALSE;
}
if (fcport->cfg.qos_enabled)
fcport->qos_attr.state = BFA_QOS_OFFLINE;
else
fcport->qos_attr.state = BFA_QOS_DISABLED;
bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
}
break;

Просмотреть файл

@ -2228,6 +2228,127 @@ bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd)
return 0;
}
int
bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
{
struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
unsigned long flags;
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;
}
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK;
return 0;
}
int
bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_qos_attr_s *iocmd = (struct bfa_bsg_qos_attr_s *)cmd;
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
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);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK;
return 0;
}
int
bfad_iocmd_qos_get_vc_attr(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_qos_vc_attr_s *iocmd =
(struct bfa_bsg_qos_vc_attr_s *)cmd;
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
unsigned long flags;
u32 i = 0;
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->attr.total_vc_count = be16_to_cpu(bfa_vc_attr->total_vc_count);
iocmd->attr.shared_credit = be16_to_cpu(bfa_vc_attr->shared_credit);
iocmd->attr.elp_opmode_flags =
be32_to_cpu(bfa_vc_attr->elp_opmode_flags);
/* Individual VC info */
while (i < iocmd->attr.total_vc_count) {
iocmd->attr.vc_info[i].vc_credit =
bfa_vc_attr->vc_info[i].vc_credit;
iocmd->attr.vc_info[i].borrow_credit =
bfa_vc_attr->vc_info[i].borrow_credit;
iocmd->attr.vc_info[i].priority =
bfa_vc_attr->vc_info[i].priority;
i++;
}
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK;
return 0;
}
int
bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_fcport_stats_s *iocmd =
(struct bfa_bsg_fcport_stats_s *)cmd;
struct bfad_hal_comp fcomp;
unsigned long flags;
struct bfa_cb_pending_q_s cb_qe;
init_completion(&fcomp.comp);
bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
&fcomp, &iocmd->stats);
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);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (iocmd->status != BFA_STATUS_OK) {
bfa_trc(bfad, iocmd->status);
goto out;
}
wait_for_completion(&fcomp.comp);
iocmd->status = fcomp.status;
out:
return 0;
}
int
bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
struct bfad_hal_comp fcomp;
unsigned long flags;
struct bfa_cb_pending_q_s cb_qe;
init_completion(&fcomp.comp);
bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
&fcomp, NULL);
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);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (iocmd->status != BFA_STATUS_OK) {
bfa_trc(bfad, iocmd->status);
goto out;
}
wait_for_completion(&fcomp.comp);
iocmd->status = fcomp.status;
out:
return 0;
}
static int
bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
unsigned int payload_len)
@ -2524,6 +2645,22 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
case IOCMD_TRUNK_GET_ATTR:
rc = bfad_iocmd_trunk_get_attr(bfad, iocmd);
break;
case IOCMD_QOS_ENABLE:
case IOCMD_QOS_DISABLE:
rc = bfad_iocmd_qos(bfad, iocmd, cmd);
break;
case IOCMD_QOS_GET_ATTR:
rc = bfad_iocmd_qos_get_attr(bfad, iocmd);
break;
case IOCMD_QOS_GET_VC_ATTR:
rc = bfad_iocmd_qos_get_vc_attr(bfad, iocmd);
break;
case IOCMD_QOS_GET_STATS:
rc = bfad_iocmd_qos_get_stats(bfad, iocmd);
break;
case IOCMD_QOS_RESET_STATS:
rc = bfad_iocmd_qos_reset_stats(bfad, iocmd);
break;
default:
rc = -EINVAL;
break;

Просмотреть файл

@ -129,6 +129,12 @@ enum {
IOCMD_TRUNK_ENABLE,
IOCMD_TRUNK_DISABLE,
IOCMD_TRUNK_GET_ATTR,
IOCMD_QOS_ENABLE,
IOCMD_QOS_DISABLE,
IOCMD_QOS_GET_ATTR,
IOCMD_QOS_GET_VC_ATTR,
IOCMD_QOS_GET_STATS,
IOCMD_QOS_RESET_STATS,
};
struct bfa_bsg_gen_s {
@ -666,6 +672,20 @@ struct bfa_bsg_trunk_attr_s {
struct bfa_trunk_attr_s attr;
};
struct bfa_bsg_qos_attr_s {
bfa_status_t status;
u16 bfad_num;
u16 rsvd;
struct bfa_qos_attr_s attr;
};
struct bfa_bsg_qos_vc_attr_s {
bfa_status_t status;
u16 bfad_num;
u16 rsvd;
struct bfa_qos_vc_attr_s attr;
};
struct bfa_bsg_fcpt_s {
bfa_status_t status;
u16 vf_id;