bnx2x: congestion management re-organization
authorYuval Mintz <yuvalmin@broadcom.com>
Tue, 3 Apr 2012 18:41:29 +0000 (18:41 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 4 Apr 2012 05:37:59 +0000 (01:37 -0400)
The congestion management code has migrated into a common location,
allowing all fw writes controlling mf congestion to be made in a
single function in the code. This is a semantic change.

Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c

index 992ddd3ecadd4d973e4a54e80714a5d2676d7ea7..c6650456aaeb7a5ec19320f4b72a9d6b1581f1a8 100644 (file)
 #if defined(CONFIG_DCB)
 #define BCM_DCBNL
 #endif
+
+
+#include "bnx2x_hsi.h"
+
 #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
 #define BCM_CNIC 1
 #include "../cnic_if.h"
@@ -1336,8 +1340,8 @@ struct bnx2x {
        struct bnx2x_common     common;
        struct bnx2x_port       port;
 
-       struct cmng_struct_per_port cmng;
-       u32                     vn_weight_sum;
+       struct cmng_init        cmng;
+
        u32                     mf_config[E1HVN_MAX];
        u32                     mf2_config[E2_FUNC_MAX];
        u32                     path_has_ovlan; /* E3 */
index 3e52d712235b76102071cd95ab003ab321687e73..be59befbf362546cd17428a643bf409704293b40 100644 (file)
@@ -964,6 +964,12 @@ static inline void bnx2x_reuse_rx_data(struct bnx2x_fastpath *fp,
 
 /************************* Init ******************************************/
 
+/* returns func by VN for current port */
+static inline int func_by_vn(struct bnx2x *bp, int vn)
+{
+       return 2 * vn + BP_PORT(bp);
+}
+
 /**
  * bnx2x_func_start - init function
  *
@@ -1419,15 +1425,32 @@ static inline void storm_memset_func_cfg(struct bnx2x *bp,
 }
 
 static inline void storm_memset_cmng(struct bnx2x *bp,
-                               struct cmng_struct_per_port *cmng,
+                               struct cmng_init *cmng,
                                u8 port)
 {
+       int vn;
        size_t size = sizeof(struct cmng_struct_per_port);
 
        u32 addr = BAR_XSTRORM_INTMEM +
                        XSTORM_CMNG_PER_PORT_VARS_OFFSET(port);
 
-       __storm_memset_struct(bp, addr, size, (u32 *)cmng);
+       __storm_memset_struct(bp, addr, size, (u32 *)&cmng->port);
+
+       for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) {
+               int func = func_by_vn(bp, vn);
+
+               addr = BAR_XSTRORM_INTMEM +
+                      XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(func);
+               size = sizeof(struct rate_shaping_vars_per_vn);
+               __storm_memset_struct(bp, addr, size,
+                                     (u32 *)&cmng->vnic.vnic_max_rate[vn]);
+
+               addr = BAR_XSTRORM_INTMEM +
+                      XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func);
+               size = sizeof(struct fairness_vars_per_vn);
+               __storm_memset_struct(bp, addr, size,
+                                     (u32 *)&cmng->vnic.vnic_min_rate[vn]);
+       }
 }
 
 /**
@@ -1608,11 +1631,6 @@ static inline void bnx2x_bz_fp(struct bnx2x *bp, int index)
  */
 void bnx2x_get_iscsi_info(struct bnx2x *bp);
 #endif
-/* returns func by VN for current port */
-static inline int func_by_vn(struct bnx2x *bp, int vn)
-{
-       return 2 * vn + BP_PORT(bp);
-}
 
 /**
  * bnx2x_link_sync_notify - send notification to other functions.
index dbff5915b81a3b998f41d1f9bed232421417791b..799272d164e5f74dfa28c5e8b86d01ef36b3db9a 100644 (file)
@@ -4448,6 +4448,65 @@ struct cmng_struct_per_port {
        struct cmng_flags_per_port flags;
 };
 
+/*
+ * a single rate shaping counter. can be used as protocol or vnic counter
+ */
+struct rate_shaping_counter {
+       u32 quota;
+#if defined(__BIG_ENDIAN)
+       u16 __reserved0;
+       u16 rate;
+#elif defined(__LITTLE_ENDIAN)
+       u16 rate;
+       u16 __reserved0;
+#endif
+};
+
+/*
+ * per-vnic rate shaping variables
+ */
+struct rate_shaping_vars_per_vn {
+       struct rate_shaping_counter vn_counter;
+};
+
+/*
+ * per-vnic fairness variables
+ */
+struct fairness_vars_per_vn {
+       u32 cos_credit_delta[MAX_COS_NUMBER];
+       u32 vn_credit_delta;
+       u32 __reserved0;
+};
+
+/*
+ * cmng port init state
+ */
+struct cmng_vnic {
+       struct rate_shaping_vars_per_vn vnic_max_rate[4];
+       struct fairness_vars_per_vn vnic_min_rate[4];
+};
+
+/*
+ * cmng port init state
+ */
+struct cmng_init {
+       struct cmng_struct_per_port port;
+       struct cmng_vnic vnic;
+};
+
+
+/*
+ * driver parameters for congestion management init, all rates are in Mbps
+ */
+struct cmng_init_input {
+       u32 port_rate;
+       u16 vnic_min_rate[4];
+       u16 vnic_max_rate[4];
+       u16 cos_min_rate[MAX_COS_NUMBER];
+       u16 cos_to_pause_mask[MAX_COS_NUMBER];
+       struct cmng_flags_per_port flags;
+};
+
 
 /*
  * Protocol-common command ID for slow path elements
@@ -4762,16 +4821,6 @@ enum fairness_mode {
 };
 
 
-/*
- * per-vnic fairness variables
- */
-struct fairness_vars_per_vn {
-       u32 cos_credit_delta[MAX_COS_NUMBER];
-       u32 vn_credit_delta;
-       u32 __reserved0;
-};
-
-
 /*
  * Priority and cos
  */
@@ -5139,29 +5188,6 @@ struct protocol_common_spe {
 };
 
 
-/*
- * a single rate shaping counter. can be used as protocol or vnic counter
- */
-struct rate_shaping_counter {
-       u32 quota;
-#if defined(__BIG_ENDIAN)
-       u16 __reserved0;
-       u16 rate;
-#elif defined(__LITTLE_ENDIAN)
-       u16 rate;
-       u16 __reserved0;
-#endif
-};
-
-
-/*
- * per-vnic rate shaping variables
- */
-struct rate_shaping_vars_per_vn {
-       struct rate_shaping_counter vn_counter;
-};
-
-
 /*
  * The send queue element
  */
index 29f5c3cca31a1a6b809749c560058a89341f5e6d..e6bb9f4c619c6b416d7531d47709f9f9b190661c 100644 (file)
@@ -241,7 +241,8 @@ static inline void bnx2x_map_q_cos(struct bnx2x *bp, u32 q_num, u32 new_cos)
                        REG_WR(bp, reg_addr, reg_bit_map | q_bit_map);
 
                        /* set/clear queue bit in command-queue bit map
-                       (E2/E3A0 only, valid COS values are 0/1) */
+                        * (E2/E3A0 only, valid COS values are 0/1)
+                        */
                        if (!(INIT_MODE_FLAGS(bp) & MODE_E3_B0)) {
                                reg_addr = BNX2X_Q_CMDQ_REG_ADDR(pf_q_num);
                                reg_bit_map = REG_RD(bp, reg_addr);
@@ -277,7 +278,215 @@ static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, enum cos_mode mode,
 }
 
 
-/* Returns the index of start or end of a specific block stage in ops array*/
+/* congestion managment port init api description
+ * the api works as follows:
+ * the driver should pass the cmng_init_input struct, the port_init function
+ * will prepare the required internal ram structure which will be passed back
+ * to the driver (cmng_init) that will write it into the internal ram.
+ *
+ * IMPORTANT REMARKS:
+ * 1. the cmng_init struct does not represent the contiguous internal ram
+ *    structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET
+ *    offset in order to write the port sub struct and the
+ *    PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other
+ *    words - don't use memcpy!).
+ * 2. although the cmng_init struct is filled for the maximal vnic number
+ *    possible, the driver should only write the valid vnics into the internal
+ *    ram according to the appropriate port mode.
+ */
+#define BITS_TO_BYTES(x) ((x)/8)
+
+/* CMNG constants, as derived from system spec calculations */
+
+/* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */
+#define DEF_MIN_RATE 100
+
+/* resolution of the rate shaping timer - 400 usec */
+#define RS_PERIODIC_TIMEOUT_USEC 400
+
+/* number of bytes in single QM arbitration cycle -
+ * coefficient for calculating the fairness timer
+ */
+#define QM_ARB_BYTES 160000
+
+/* resolution of Min algorithm 1:100 */
+#define MIN_RES 100
+
+/* how many bytes above threshold for
+ * the minimal credit of Min algorithm
+ */
+#define MIN_ABOVE_THRESH 32768
+
+/* Fairness algorithm integration time coefficient -
+ * for calculating the actual Tfair
+ */
+#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES)
+
+/* Memory of fairness algorithm - 2 cycles */
+#define FAIR_MEM 2
+#define SAFC_TIMEOUT_USEC 52
+
+#define SDM_TICKS 4
+
+
+static inline void bnx2x_init_max(const struct cmng_init_input *input_data,
+                                 u32 r_param, struct cmng_init *ram_data)
+{
+       u32 vnic;
+       struct cmng_vnic *vdata = &ram_data->vnic;
+       struct cmng_struct_per_port *pdata = &ram_data->port;
+       /* rate shaping per-port variables
+        * 100 micro seconds in SDM ticks = 25
+        * since each tick is 4 microSeconds
+        */
+
+       pdata->rs_vars.rs_periodic_timeout =
+       RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS;
+
+       /* this is the threshold below which no timer arming will occur.
+        * 1.25 coefficient is for the threshold to be a little bigger
+        * then the real time to compensate for timer in-accuracy
+        */
+       pdata->rs_vars.rs_threshold =
+       (5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4;
+
+       /* rate shaping per-vnic variables */
+       for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
+               /* global vnic counter */
+               vdata->vnic_max_rate[vnic].vn_counter.rate =
+               input_data->vnic_max_rate[vnic];
+               /* maximal Mbps for this vnic
+                * the quota in each timer period - number of bytes
+                * transmitted in this period
+                */
+               vdata->vnic_max_rate[vnic].vn_counter.quota =
+                       RS_PERIODIC_TIMEOUT_USEC *
+                       (u32)vdata->vnic_max_rate[vnic].vn_counter.rate / 8;
+       }
+
+}
+
+static inline void bnx2x_init_min(const struct cmng_init_input *input_data,
+                                 u32 r_param, struct cmng_init *ram_data)
+{
+       u32 vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair;
+       struct cmng_vnic *vdata = &ram_data->vnic;
+       struct cmng_struct_per_port *pdata = &ram_data->port;
+
+       /* this is the resolution of the fairness timer */
+       fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
+
+       /* fairness per-port variables
+        * for 10G it is 1000usec. for 1G it is 10000usec.
+        */
+       tFair = T_FAIR_COEF / input_data->port_rate;
+
+       /* this is the threshold below which we won't arm the timer anymore */
+       pdata->fair_vars.fair_threshold = QM_ARB_BYTES;
+
+       /* we multiply by 1e3/8 to get bytes/msec. We don't want the credits
+        * to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution)
+        */
+       pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM;
+
+       /* since each tick is 4 microSeconds */
+       pdata->fair_vars.fairness_timeout =
+                               fair_periodic_timeout_usec / SDM_TICKS;
+
+       /* calculate sum of weights */
+       vnicWeightSum = 0;
+
+       for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++)
+               vnicWeightSum += input_data->vnic_min_rate[vnic];
+
+       /* global vnic counter */
+       if (vnicWeightSum > 0) {
+               /* fairness per-vnic variables */
+               for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
+                       /* this is the credit for each period of the fairness
+                        * algorithm - number of bytes in T_FAIR (this vnic
+                        * share of the port rate)
+                        */
+                       vdata->vnic_min_rate[vnic].vn_credit_delta =
+                               (u32)input_data->vnic_min_rate[vnic] * 100 *
+                               T_FAIR_COEF / (8 * 100 * vnicWeightSum);
+                       if (vdata->vnic_min_rate[vnic].vn_credit_delta <
+                           pdata->fair_vars.fair_threshold +
+                           MIN_ABOVE_THRESH) {
+                               vdata->vnic_min_rate[vnic].vn_credit_delta =
+                                       pdata->fair_vars.fair_threshold +
+                                       MIN_ABOVE_THRESH;
+                       }
+               }
+       }
+}
+
+static inline void bnx2x_init_fw_wrr(const struct cmng_init_input *input_data,
+                                    u32 r_param, struct cmng_init *ram_data)
+{
+       u32 vnic, cos;
+       u32 cosWeightSum = 0;
+       struct cmng_vnic *vdata = &ram_data->vnic;
+       struct cmng_struct_per_port *pdata = &ram_data->port;
+
+       for (cos = 0; cos < MAX_COS_NUMBER; cos++)
+               cosWeightSum += input_data->cos_min_rate[cos];
+
+       if (cosWeightSum > 0) {
+
+               for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
+                       /* Since cos and vnic shouldn't work together the rate
+                        * to divide between the coses is the port rate.
+                        */
+                       u32 *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta;
+                       for (cos = 0; cos < MAX_COS_NUMBER; cos++) {
+                               /* this is the credit for each period of
+                                * the fairness algorithm - number of bytes
+                                * in T_FAIR (this cos share of the vnic rate)
+                                */
+                               ccd[cos] =
+                                   (u32)input_data->cos_min_rate[cos] * 100 *
+                                   T_FAIR_COEF / (8 * 100 * cosWeightSum);
+                                if (ccd[cos] < pdata->fair_vars.fair_threshold
+                                               + MIN_ABOVE_THRESH) {
+                                       ccd[cos] =
+                                           pdata->fair_vars.fair_threshold +
+                                           MIN_ABOVE_THRESH;
+                               }
+                       }
+               }
+       }
+}
+
+static inline void bnx2x_init_safc(const struct cmng_init_input *input_data,
+                                  struct cmng_init *ram_data)
+{
+       /* in microSeconds */
+       ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC;
+}
+
+/* Congestion management port init */
+static inline void bnx2x_init_cmng(const struct cmng_init_input *input_data,
+                                  struct cmng_init *ram_data)
+{
+       u32 r_param;
+       memset(ram_data, 0, sizeof(struct cmng_init));
+
+       ram_data->port.flags = input_data->flags;
+
+       /* number of bytes transmitted in a rate of 10Gbps
+        * in one usec = 1.25KB.
+        */
+       r_param = BITS_TO_BYTES(input_data->port_rate);
+       bnx2x_init_max(input_data, r_param, ram_data);
+       bnx2x_init_min(input_data, r_param, ram_data);
+       bnx2x_init_fw_wrr(input_data, r_param, ram_data);
+       bnx2x_init_safc(input_data, ram_data);
+}
+
+
+
+/* Returns the index of start or end of a specific block stage in ops array */
 #define BLOCK_OPS_IDX(block, stage, end) \
                        (2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
 
@@ -499,9 +708,7 @@ static inline void bnx2x_disable_blocks_parity(struct bnx2x *bp)
        bnx2x_set_mcp_parity(bp, false);
 }
 
-/**
- * Clear the parity error status registers.
- */
+/* Clear the parity error status registers. */
 static inline void bnx2x_clear_blocks_parity(struct bnx2x *bp)
 {
        int i;
index bca99b20206c88d94932f251822a0fb95336e424..495a646e719d91ee05141d6e9663308d30b68b3c 100644 (file)
@@ -2160,40 +2160,6 @@ u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes)
        return rc;
 }
 
-static void bnx2x_init_port_minmax(struct bnx2x *bp)
-{
-       u32 r_param = bp->link_vars.line_speed / 8;
-       u32 fair_periodic_timeout_usec;
-       u32 t_fair;
-
-       memset(&(bp->cmng.rs_vars), 0,
-              sizeof(struct rate_shaping_vars_per_port));
-       memset(&(bp->cmng.fair_vars), 0, sizeof(struct fairness_vars_per_port));
-
-       /* 100 usec in SDM ticks = 25 since each tick is 4 usec */
-       bp->cmng.rs_vars.rs_periodic_timeout = RS_PERIODIC_TIMEOUT_USEC / 4;
-
-       /* this is the threshold below which no timer arming will occur
-          1.25 coefficient is for the threshold to be a little bigger
-          than the real time, to compensate for timer in-accuracy */
-       bp->cmng.rs_vars.rs_threshold =
-                               (RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4;
-
-       /* resolution of fairness timer */
-       fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
-       /* for 10G it is 1000usec. for 1G it is 10000usec. */
-       t_fair = T_FAIR_COEF / bp->link_vars.line_speed;
-
-       /* this is the threshold below which we won't arm the timer anymore */
-       bp->cmng.fair_vars.fair_threshold = QM_ARB_BYTES;
-
-       /* we multiply by 1e3/8 to get bytes/msec.
-          We don't want the credits to pass a credit
-          of the t_fair*FAIR_MEM (algorithm resolution) */
-       bp->cmng.fair_vars.upper_bound = r_param * t_fair * FAIR_MEM;
-       /* since each tick is 4 usec */
-       bp->cmng.fair_vars.fairness_timeout = fair_periodic_timeout_usec / 4;
-}
 
 /* Calculates the sum of vn_min_rates.
    It's needed for further normalizing of the min_rates.
@@ -2204,12 +2170,12 @@ static void bnx2x_init_port_minmax(struct bnx2x *bp)
      In the later case fainess algorithm should be deactivated.
      If not all min_rates are zero then those that are zeroes will be set to 1.
  */
-static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
+static void bnx2x_calc_vn_min(struct bnx2x *bp,
+                                     struct cmng_init_input *input)
 {
        int all_zero = 1;
        int vn;
 
-       bp->vn_weight_sum = 0;
        for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) {
                u32 vn_cfg = bp->mf_config[vn];
                u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
@@ -2217,106 +2183,56 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
 
                /* Skip hidden vns */
                if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE)
-                       continue;
-
+                       vn_min_rate = 0;
                /* If min rate is zero - set it to 1 */
-               if (!vn_min_rate)
+               else if (!vn_min_rate)
                        vn_min_rate = DEF_MIN_RATE;
                else
                        all_zero = 0;
 
-               bp->vn_weight_sum += vn_min_rate;
+               input->vnic_min_rate[vn] = vn_min_rate;
        }
 
        /* if ETS or all min rates are zeros - disable fairness */
        if (BNX2X_IS_ETS_ENABLED(bp)) {
-               bp->cmng.flags.cmng_enables &=
+               input->flags.cmng_enables &=
                                        ~CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
                DP(NETIF_MSG_IFUP, "Fairness will be disabled due to ETS\n");
        } else if (all_zero) {
-               bp->cmng.flags.cmng_enables &=
+               input->flags.cmng_enables &=
                                        ~CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
-               DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
-                  "  fairness will be disabled\n");
+               DP(NETIF_MSG_IFUP,
+                  "All MIN values are zeroes fairness will be disabled\n");
        } else
-               bp->cmng.flags.cmng_enables |=
+               input->flags.cmng_enables |=
                                        CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
 }
 
-static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn)
+static void bnx2x_calc_vn_max(struct bnx2x *bp, int vn,
+                                   struct cmng_init_input *input)
 {
-       struct rate_shaping_vars_per_vn m_rs_vn;
-       struct fairness_vars_per_vn m_fair_vn;
+       u16 vn_max_rate;
        u32 vn_cfg = bp->mf_config[vn];
-       int func = func_by_vn(bp, vn);
-       u16 vn_min_rate, vn_max_rate;
-       int i;
 
-       /* If function is hidden - set min and max to zeroes */
-       if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE) {
-               vn_min_rate = 0;
+       if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE)
                vn_max_rate = 0;
-
-       } else {
+       else {
                u32 maxCfg = bnx2x_extract_max_cfg(bp, vn_cfg);
 
-               vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
-                               FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
-               /* If fairness is enabled (not all min rates are zeroes) and
-                  if current min rate is zero - set it to 1.
-                  This is a requirement of the algorithm. */
-               if (bp->vn_weight_sum && (vn_min_rate == 0))
-                       vn_min_rate = DEF_MIN_RATE;
-
-               if (IS_MF_SI(bp))
+               if (IS_MF_SI(bp)) {
                        /* maxCfg in percents of linkspeed */
                        vn_max_rate = (bp->link_vars.line_speed * maxCfg) / 100;
-               else
+               } else /* SD modes */
                        /* maxCfg is absolute in 100Mb units */
                        vn_max_rate = maxCfg * 100;
        }
 
-       DP(NETIF_MSG_IFUP,
-          "func %d: vn_min_rate %d  vn_max_rate %d  vn_weight_sum %d\n",
-          func, vn_min_rate, vn_max_rate, bp->vn_weight_sum);
-
-       memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn));
-       memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn));
-
-       /* global vn counter - maximal Mbps for this vn */
-       m_rs_vn.vn_counter.rate = vn_max_rate;
-
-       /* quota - number of bytes transmitted in this period */
-       m_rs_vn.vn_counter.quota =
-                               (vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8;
-
-       if (bp->vn_weight_sum) {
-               /* credit for each period of the fairness algorithm:
-                  number of bytes in T_FAIR (the vn share the port rate).
-                  vn_weight_sum should not be larger than 10000, thus
-                  T_FAIR_COEF / (8 * vn_weight_sum) will always be greater
-                  than zero */
-               m_fair_vn.vn_credit_delta =
-                       max_t(u32, (vn_min_rate * (T_FAIR_COEF /
-                                                  (8 * bp->vn_weight_sum))),
-                             (bp->cmng.fair_vars.fair_threshold +
-                                                       MIN_ABOVE_THRESH));
-               DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta %d\n",
-                  m_fair_vn.vn_credit_delta);
-       }
-
-       /* Store it to internal memory */
-       for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++)
-               REG_WR(bp, BAR_XSTRORM_INTMEM +
-                      XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(func) + i * 4,
-                      ((u32 *)(&m_rs_vn))[i]);
-
-       for (i = 0; i < sizeof(struct fairness_vars_per_vn)/4; i++)
-               REG_WR(bp, BAR_XSTRORM_INTMEM +
-                      XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + i * 4,
-                      ((u32 *)(&m_fair_vn))[i]);
+       DP(NETIF_MSG_IFUP, "vn %d: vn_max_rate %d\n", vn, vn_max_rate);
+
+       input->vnic_max_rate[vn] = vn_max_rate;
 }
 
+
 static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp)
 {
        if (CHIP_REV_IS_SLOW(bp))
@@ -2358,34 +2274,31 @@ void bnx2x_read_mf_cfg(struct bnx2x *bp)
 
 static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type)
 {
+       struct cmng_init_input input;
+       memset(&input, 0, sizeof(struct cmng_init_input));
+
+       input.port_rate = bp->link_vars.line_speed;
 
        if (cmng_type == CMNG_FNS_MINMAX) {
                int vn;
 
-               /* clear cmng_enables */
-               bp->cmng.flags.cmng_enables = 0;
-
                /* read mf conf from shmem */
                if (read_cfg)
                        bnx2x_read_mf_cfg(bp);
 
-               /* Init rate shaping and fairness contexts */
-               bnx2x_init_port_minmax(bp);
-
                /* vn_weight_sum and enable fairness if not 0 */
-               bnx2x_calc_vn_weight_sum(bp);
+               bnx2x_calc_vn_min(bp, &input);
 
                /* calculate and set min-max rate for each vn */
                if (bp->port.pmf)
                        for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++)
-                               bnx2x_init_vn_minmax(bp, vn);
+                               bnx2x_calc_vn_max(bp, vn, &input);
 
                /* always enable rate shaping and fairness */
-               bp->cmng.flags.cmng_enables |=
+               input.flags.cmng_enables |=
                                        CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
-               if (!bp->vn_weight_sum)
-                       DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
-                                  "  fairness will be disabled\n");
+
+               bnx2x_init_cmng(&input, &bp->cmng);
                return;
        }