[SCSI] bfa: Add support for user to configure bandwidth on QoS priorities
authorKrishna Gudipati <kgudipat@brocade.com>
Sat, 22 Sep 2012 00:26:31 +0000 (17:26 -0700)
committerJames Bottomley <JBottomley@Parallels.com>
Sun, 7 Oct 2012 10:20:08 +0000 (11:20 +0100)
Made changes to provide an option for user to configure the
bandwidth percentage for High/Medium/Low QoS priorities.

Signed-off-by: Sudarsana Reddy Kalluru <skalluru@brocade.com>
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/bfa/bfa_defs.h
drivers/scsi/bfa/bfa_defs_svc.h
drivers/scsi/bfa/bfa_svc.c
drivers/scsi/bfa/bfa_svc.h
drivers/scsi/bfa/bfad_bsg.c
drivers/scsi/bfa/bfad_bsg.h

index b4d5d87f54ff9e1f01b8aac471f95b3b1495c473..f8df2c94978659a12c8c6f0a0104cfe7d176c84b 100644 (file)
@@ -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 */
index 76ea10d37ad700c32c913421d7770d34e3302754..18e4f6ba70d2bb28c9ddae64e5446f231897c2a5 100644 (file)
@@ -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];
 };
 
 /*
index 309ab2ad3ce95bdeba02930338e5cf9048e0464e..299c1c889b3389d36d896756e638fb6867d91dee 100644 (file)
@@ -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)
 {
index 1854ca3bc1a516bf69269e74dda865a853cb4415..8d7fbecfcb22d52bafb16b333bd35019ac6c0271 100644 (file)
@@ -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);
index 69b1ba9e58f6987c8ef51ebcc4bdb99621aa199c..90c40e4e2d4b0633dcfe991cc78bb6bddb855082 100644 (file)
@@ -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;
index 62f1b8809d19d0258c6b9a7c1acac77a0bb86210..b67a2292cff394606d8767b8e78d401e90ebc5de 100644 (file)
@@ -144,6 +144,7 @@ enum {
        IOCMD_DIAG_DPORT_ENABLE,
        IOCMD_DIAG_DPORT_DISABLE,
        IOCMD_DIAG_DPORT_GET_STATE,
+       IOCMD_QOS_SET_BW,
 };
 
 struct bfa_bsg_gen_s {
@@ -704,6 +705,13 @@ struct bfa_bsg_qos_vc_attr_s {
        struct bfa_qos_vc_attr_s attr;
 };
 
+struct bfa_bsg_qos_bw_s {
+       bfa_status_t    status;
+       u16             bfad_num;
+       u16             rsvd;
+       struct bfa_qos_bw_s qos_bw;
+};
+
 struct bfa_bsg_vf_stats_s {
        bfa_status_t    status;
        u16             bfad_num;