Commit 6894f013 authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley
Browse files

[SCSI] bfa: Add support for user to configure bandwidth on QoS priorities



Made changes to provide an option for user to configure the
bandwidth percentage for High/Medium/Low QoS priorities.

Signed-off-by: default avatarSudarsana Reddy Kalluru <skalluru@brocade.com>
Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 04ea6575
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -190,6 +190,8 @@ enum bfa_status {
	BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */
	BFA_STATUS_LOOP_UNSUPP_MEZZ = 231, /* Loop topology is not supported
					    * on mezz cards */
	BFA_STATUS_QOS_BW_INVALID = 234,   /* Invalid QOS bandwidth
					    * configuration */
	BFA_STATUS_DPORT_ENABLED = 235, /* D-port mode is already enabled */
	BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */
	BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */
+12 −3
Original line number Diff line number Diff line
@@ -522,6 +522,14 @@ enum bfa_qos_bw_alloc {
	BFA_QOS_BW_LOW  =  10,	/*  bandwidth allocation for Low */
};
#pragma pack(1)

struct bfa_qos_bw_s {
	u8	qos_bw_set;
	u8	high;
	u8	med;
	u8	low;
};

/*
 * QoS attribute returned in QoS Query
 */
@@ -529,7 +537,8 @@ struct bfa_qos_attr_s {
	u8	state;		/*  QoS current state */
	u8	rsvd1[3];
	u32	total_bb_cr;	/*  Total BB Credits */
	u32	rsvd2[2];
	struct bfa_qos_bw_s qos_bw;	/* QOS bw cfg */
	struct bfa_qos_bw_s qos_bw_op;	/* QOS bw operational */
};

/*
@@ -887,7 +896,7 @@ struct bfa_port_cfg_s {
	u8	 rsvd1;
	u16	 path_tov;	/*  device path timeout	*/
	u16	 q_depth;	/*  SCSI Queue depth		*/
	u32	 rsvd2;
	struct bfa_qos_bw_s qos_bw;	/* QOS bandwidth	*/
};
#pragma pack()

@@ -935,7 +944,7 @@ struct bfa_port_attr_s {

	/* FCoE specific  */
	u16			fcoe_vlan;
	u8			rsvd1[2];
	u8			rsvd1[6];
};

/*
+44 −2
Original line number Diff line number Diff line
@@ -3067,6 +3067,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
	 */
	do_gettimeofday(&tv);
	fcport->stats_reset_time = tv.tv_sec;
	fcport->stats_dma_ready = BFA_FALSE;

	/*
	 * initialize and set default configuration
@@ -3077,6 +3078,9 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
	port_cfg->maxfrsize = 0;

	port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS;
	port_cfg->qos_bw.high = BFA_QOS_BW_HIGH;
	port_cfg->qos_bw.med = BFA_QOS_BW_MED;
	port_cfg->qos_bw.low = BFA_QOS_BW_LOW;

	INIT_LIST_HEAD(&fcport->stats_pending_q);
	INIT_LIST_HEAD(&fcport->statsclr_pending_q);
@@ -3596,6 +3600,7 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
	case BFI_FCPORT_I2H_ENABLE_RSP:
		if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) {

			fcport->stats_dma_ready = BFA_TRUE;
			if (fcport->use_flash_cfg) {
				fcport->cfg = i2hmsg.penable_rsp->port_cfg;
				fcport->cfg.maxfrsize =
@@ -3611,6 +3616,8 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
				else
					fcport->trunk.attr.state =
						BFA_TRUNK_DISABLED;
				fcport->qos_attr.qos_bw =
					i2hmsg.penable_rsp->port_cfg.qos_bw;
				fcport->use_flash_cfg = BFA_FALSE;
			}

@@ -3619,6 +3626,9 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
			else
				fcport->qos_attr.state = BFA_QOS_DISABLED;

			fcport->qos_attr.qos_bw_op =
					i2hmsg.penable_rsp->port_cfg.qos_bw;

			bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
		}
		break;
@@ -3640,6 +3650,8 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
				bfa_sm_send_event(fcport,
						  BFA_FCPORT_SM_LINKDOWN);
		}
		fcport->qos_attr.qos_bw_op =
				i2hmsg.event->link_state.qos_attr.qos_bw_op;
		break;

	case BFI_FCPORT_I2H_TRUNK_SCN:
@@ -4035,8 +4047,9 @@ bfa_fcport_get_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb)
{
	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);

	if (bfa_ioc_is_disabled(&bfa->ioc))
		return BFA_STATUS_IOC_DISABLED;
	if (!bfa_iocfc_is_operational(bfa) ||
	    !fcport->stats_dma_ready)
		return BFA_STATUS_IOC_NON_OP;

	if (!list_empty(&fcport->statsclr_pending_q))
		return BFA_STATUS_DEVBUSY;
@@ -4061,6 +4074,10 @@ bfa_fcport_clear_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb)
{
	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);

	if (!bfa_iocfc_is_operational(bfa) ||
	    !fcport->stats_dma_ready)
		return BFA_STATUS_IOC_NON_OP;

	if (!list_empty(&fcport->stats_pending_q))
		return BFA_STATUS_DEVBUSY;

@@ -4098,6 +4115,31 @@ bfa_fcport_is_dport(struct bfa_s *bfa)
		BFA_PORT_ST_DPORT);
}

bfa_status_t
bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw)
{
	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
	enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);

	bfa_trc(bfa, ioc_type);

	if ((qos_bw->high == 0) || (qos_bw->med == 0) || (qos_bw->low == 0))
		return BFA_STATUS_QOS_BW_INVALID;

	if ((qos_bw->high + qos_bw->med + qos_bw->low) != 100)
		return BFA_STATUS_QOS_BW_INVALID;

	if ((qos_bw->med > qos_bw->high) || (qos_bw->low > qos_bw->med) ||
	    (qos_bw->low > qos_bw->high))
		return BFA_STATUS_QOS_BW_INVALID;

	if ((ioc_type == BFA_IOC_TYPE_FC) &&
	    (fcport->cfg.topology != BFA_PORT_TOPOLOGY_LOOP))
		fcport->cfg.qos_bw = *qos_bw;

	return BFA_STATUS_OK;
}

bfa_boolean_t
bfa_fcport_is_ratelim(struct bfa_s *bfa)
{
+3 −0
Original line number Diff line number Diff line
@@ -514,6 +514,7 @@ struct bfa_fcport_s {
	struct bfa_fcport_trunk_s trunk;
	u16		fcoe_vlan;
	struct bfa_mem_dma_s	fcport_dma;
	bfa_boolean_t		stats_dma_ready;
};

#define BFA_FCPORT_MOD(__bfa)	(&(__bfa)->modules.fcport)
@@ -551,6 +552,8 @@ void bfa_fcport_event_register(struct bfa_s *bfa,
			enum bfa_port_linkstate event), void *event_cbarg);
bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa);
bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa,
				   struct bfa_qos_bw_s *qos_bw);
enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);

void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn);
+25 −1
Original line number Diff line number Diff line
@@ -879,6 +879,19 @@ out:
	return 0;
}

int
bfad_iocmd_qos_set_bw(struct bfad_s *bfad, void *pcmd)
{
	struct bfa_bsg_qos_bw_s *iocmd = (struct bfa_bsg_qos_bw_s *)pcmd;
	unsigned long	flags;

	spin_lock_irqsave(&bfad->bfad_lock, flags);
	iocmd->status = bfa_fcport_set_qos_bw(&bfad->bfa, &iocmd->qos_bw);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);

	return 0;
}

int
bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
{
@@ -2284,8 +2297,12 @@ bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
		else {
			if (v_cmd == IOCMD_QOS_ENABLE)
				fcport->cfg.qos_enabled = BFA_TRUE;
			else if (v_cmd == IOCMD_QOS_DISABLE)
			else if (v_cmd == IOCMD_QOS_DISABLE) {
				fcport->cfg.qos_enabled = BFA_FALSE;
				fcport->cfg.qos_bw.high = BFA_QOS_BW_HIGH;
				fcport->cfg.qos_bw.med = BFA_QOS_BW_MED;
				fcport->cfg.qos_bw.low = BFA_QOS_BW_LOW;
			}
		}
	}
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -2308,6 +2325,10 @@ bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd)
		iocmd->attr.state = fcport->qos_attr.state;
		iocmd->attr.total_bb_cr =
			be32_to_cpu(fcport->qos_attr.total_bb_cr);
		iocmd->attr.qos_bw.high = fcport->cfg.qos_bw.high;
		iocmd->attr.qos_bw.med = fcport->cfg.qos_bw.med;
		iocmd->attr.qos_bw.low = fcport->cfg.qos_bw.low;
		iocmd->attr.qos_bw_op = fcport->qos_attr.qos_bw_op;
		iocmd->status = BFA_STATUS_OK;
	}
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -2839,6 +2860,9 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
	case IOCMD_QOS_RESET_STATS:
		rc = bfad_iocmd_qos_reset_stats(bfad, iocmd);
		break;
	case IOCMD_QOS_SET_BW:
		rc = bfad_iocmd_qos_set_bw(bfad, iocmd);
		break;
	case IOCMD_VF_GET_STATS:
		rc = bfad_iocmd_vf_get_stats(bfad, iocmd);
		break;
Loading