bnx2x: BW shaper enhancements
Some of the configuration can be set when loading the device and shouldn't be re-calculated after each link up indication since it is not dependent on the link speed Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
748e543974
Коммит
8a1c38d17d
|
@ -883,6 +883,9 @@ struct bnx2x {
|
||||||
struct bnx2x_common common;
|
struct bnx2x_common common;
|
||||||
struct bnx2x_port port;
|
struct bnx2x_port port;
|
||||||
|
|
||||||
|
struct cmng_struct_per_port cmng;
|
||||||
|
u32 vn_weight_sum;
|
||||||
|
|
||||||
u32 mf_config;
|
u32 mf_config;
|
||||||
u16 e1hov;
|
u16 e1hov;
|
||||||
u8 e1hmf;
|
u8 e1hmf;
|
||||||
|
|
|
@ -2640,17 +2640,19 @@ struct ustorm_eth_rx_producers {
|
||||||
*/
|
*/
|
||||||
struct cmng_flags_per_port {
|
struct cmng_flags_per_port {
|
||||||
u8 con_number[NUM_OF_PROTOCOLS];
|
u8 con_number[NUM_OF_PROTOCOLS];
|
||||||
#if defined(__BIG_ENDIAN)
|
u32 cmng_enables;
|
||||||
u8 fairness_enable;
|
#define CMNG_FLAGS_PER_PORT_FAIRNESS_VN (0x1<<0)
|
||||||
u8 rate_shaping_enable;
|
#define CMNG_FLAGS_PER_PORT_FAIRNESS_VN_SHIFT 0
|
||||||
u8 cmng_protocol_enable;
|
#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN (0x1<<1)
|
||||||
u8 cmng_vn_enable;
|
#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN_SHIFT 1
|
||||||
#elif defined(__LITTLE_ENDIAN)
|
#define CMNG_FLAGS_PER_PORT_FAIRNESS_PROTOCOL (0x1<<2)
|
||||||
u8 cmng_vn_enable;
|
#define CMNG_FLAGS_PER_PORT_FAIRNESS_PROTOCOL_SHIFT 2
|
||||||
u8 cmng_protocol_enable;
|
#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL (0x1<<3)
|
||||||
u8 rate_shaping_enable;
|
#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL_SHIFT 3
|
||||||
u8 fairness_enable;
|
#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS (0x1<<4)
|
||||||
#endif
|
#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_SHIFT 4
|
||||||
|
#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x7FFFFFF<<5)
|
||||||
|
#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2803,6 +2805,7 @@ struct eth_stats_query {
|
||||||
* per-vnic fairness variables
|
* per-vnic fairness variables
|
||||||
*/
|
*/
|
||||||
struct fairness_vars_per_vn {
|
struct fairness_vars_per_vn {
|
||||||
|
u32 cos_credit_delta[MAX_COS_NUMBER];
|
||||||
u32 protocol_credit_delta[NUM_OF_PROTOCOLS];
|
u32 protocol_credit_delta[NUM_OF_PROTOCOLS];
|
||||||
u32 vn_credit_delta;
|
u32 vn_credit_delta;
|
||||||
u32 __reserved0;
|
u32 __reserved0;
|
||||||
|
|
|
@ -2054,119 +2054,42 @@ static u8 bnx2x_link_test(struct bnx2x *bp)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculates the sum of vn_min_rates.
|
static void bnx2x_init_port_minmax(struct bnx2x *bp)
|
||||||
It's needed for further normalizing of the min_rates.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
sum of vn_min_rates
|
|
||||||
or
|
|
||||||
0 - if all the min_rates are 0.
|
|
||||||
In the later case fairness algorithm should be deactivated.
|
|
||||||
If not all min_rates are zero then those that are zeroes will
|
|
||||||
be set to 1.
|
|
||||||
*/
|
|
||||||
static u32 bnx2x_calc_vn_wsum(struct bnx2x *bp)
|
|
||||||
{
|
{
|
||||||
int i, port = BP_PORT(bp);
|
u32 r_param = bp->link_vars.line_speed / 8;
|
||||||
u32 wsum = 0;
|
u32 fair_periodic_timeout_usec;
|
||||||
int all_zero = 1;
|
u32 t_fair;
|
||||||
|
|
||||||
for (i = 0; i < E1HVN_MAX; i++) {
|
memset(&(bp->cmng.rs_vars), 0,
|
||||||
u32 vn_cfg =
|
sizeof(struct rate_shaping_vars_per_port));
|
||||||
SHMEM_RD(bp, mf_cfg.func_mf_config[2*i + port].config);
|
memset(&(bp->cmng.fair_vars), 0, sizeof(struct fairness_vars_per_port));
|
||||||
u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
|
|
||||||
FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
|
|
||||||
if (!(vn_cfg & FUNC_MF_CFG_FUNC_HIDE)) {
|
|
||||||
/* If min rate is zero - set it to 1 */
|
|
||||||
if (!vn_min_rate)
|
|
||||||
vn_min_rate = DEF_MIN_RATE;
|
|
||||||
else
|
|
||||||
all_zero = 0;
|
|
||||||
|
|
||||||
wsum += vn_min_rate;
|
/* 100 usec in SDM ticks = 25 since each tick is 4 usec */
|
||||||
}
|
bp->cmng.rs_vars.rs_periodic_timeout = RS_PERIODIC_TIMEOUT_USEC / 4;
|
||||||
}
|
|
||||||
|
|
||||||
/* ... only if all min rates are zeros - disable FAIRNESS */
|
/* this is the threshold below which no timer arming will occur
|
||||||
if (all_zero)
|
1.25 coefficient is for the threshold to be a little bigger
|
||||||
return 0;
|
than the real time, to compensate for timer in-accuracy */
|
||||||
|
bp->cmng.rs_vars.rs_threshold =
|
||||||
return wsum;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnx2x_init_port_minmax(struct bnx2x *bp,
|
|
||||||
int en_fness,
|
|
||||||
u16 port_rate,
|
|
||||||
struct cmng_struct_per_port *m_cmng_port)
|
|
||||||
{
|
|
||||||
u32 r_param = port_rate / 8;
|
|
||||||
int port = BP_PORT(bp);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(m_cmng_port, 0, sizeof(struct cmng_struct_per_port));
|
|
||||||
|
|
||||||
/* Enable minmax only if we are in e1hmf mode */
|
|
||||||
if (IS_E1HMF(bp)) {
|
|
||||||
u32 fair_periodic_timeout_usec;
|
|
||||||
u32 t_fair;
|
|
||||||
|
|
||||||
/* Enable rate shaping and fairness */
|
|
||||||
m_cmng_port->flags.cmng_vn_enable = 1;
|
|
||||||
m_cmng_port->flags.fairness_enable = en_fness ? 1 : 0;
|
|
||||||
m_cmng_port->flags.rate_shaping_enable = 1;
|
|
||||||
|
|
||||||
if (!en_fness)
|
|
||||||
DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
|
|
||||||
" fairness will be disabled\n");
|
|
||||||
|
|
||||||
/* 100 usec in SDM ticks = 25 since each tick is 4 usec */
|
|
||||||
m_cmng_port->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 */
|
|
||||||
m_cmng_port->rs_vars.rs_threshold =
|
|
||||||
(RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4;
|
(RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4;
|
||||||
|
|
||||||
/* resolution of fairness timer */
|
/* resolution of fairness timer */
|
||||||
fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
|
fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
|
||||||
/* for 10G it is 1000usec. for 1G it is 10000usec. */
|
/* for 10G it is 1000usec. for 1G it is 10000usec. */
|
||||||
t_fair = T_FAIR_COEF / port_rate;
|
t_fair = T_FAIR_COEF / bp->link_vars.line_speed;
|
||||||
|
|
||||||
/* this is the threshold below which we won't arm
|
/* this is the threshold below which we won't arm the timer anymore */
|
||||||
the timer anymore */
|
bp->cmng.fair_vars.fair_threshold = QM_ARB_BYTES;
|
||||||
m_cmng_port->fair_vars.fair_threshold = QM_ARB_BYTES;
|
|
||||||
|
|
||||||
/* we multiply by 1e3/8 to get bytes/msec.
|
/* we multiply by 1e3/8 to get bytes/msec.
|
||||||
We don't want the credits to pass a credit
|
We don't want the credits to pass a credit
|
||||||
of the T_FAIR*FAIR_MEM (algorithm resolution) */
|
of the t_fair*FAIR_MEM (algorithm resolution) */
|
||||||
m_cmng_port->fair_vars.upper_bound =
|
bp->cmng.fair_vars.upper_bound = r_param * t_fair * FAIR_MEM;
|
||||||
r_param * t_fair * FAIR_MEM;
|
/* since each tick is 4 usec */
|
||||||
/* since each tick is 4 usec */
|
bp->cmng.fair_vars.fairness_timeout = fair_periodic_timeout_usec / 4;
|
||||||
m_cmng_port->fair_vars.fairness_timeout =
|
|
||||||
fair_periodic_timeout_usec / 4;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* Disable rate shaping and fairness */
|
|
||||||
m_cmng_port->flags.cmng_vn_enable = 0;
|
|
||||||
m_cmng_port->flags.fairness_enable = 0;
|
|
||||||
m_cmng_port->flags.rate_shaping_enable = 0;
|
|
||||||
|
|
||||||
DP(NETIF_MSG_IFUP,
|
|
||||||
"Single function mode minmax will be disabled\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store it to internal memory */
|
|
||||||
for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
|
|
||||||
REG_WR(bp, BAR_XSTRORM_INTMEM +
|
|
||||||
XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
|
|
||||||
((u32 *)(m_cmng_port))[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
|
static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
|
||||||
u32 wsum, u16 port_rate,
|
|
||||||
struct cmng_struct_per_port *m_cmng_port)
|
|
||||||
{
|
{
|
||||||
struct rate_shaping_vars_per_vn m_rs_vn;
|
struct rate_shaping_vars_per_vn m_rs_vn;
|
||||||
struct fairness_vars_per_vn m_fair_vn;
|
struct fairness_vars_per_vn m_fair_vn;
|
||||||
|
@ -2182,17 +2105,18 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
|
||||||
} else {
|
} else {
|
||||||
vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
|
vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
|
||||||
FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
|
FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
|
||||||
/* If FAIRNESS is enabled (not all min rates are zeroes) and
|
/* If fairness is enabled (not all min rates are zeroes) and
|
||||||
if current min rate is zero - set it to 1.
|
if current min rate is zero - set it to 1.
|
||||||
This is a requirement of the algorithm. */
|
This is a requirement of the algorithm. */
|
||||||
if ((vn_min_rate == 0) && wsum)
|
if (bp->vn_weight_sum && (vn_min_rate == 0))
|
||||||
vn_min_rate = DEF_MIN_RATE;
|
vn_min_rate = DEF_MIN_RATE;
|
||||||
vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
|
vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
|
||||||
FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
|
FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
DP(NETIF_MSG_IFUP, "func %d: vn_min_rate=%d vn_max_rate=%d "
|
DP(NETIF_MSG_IFUP,
|
||||||
"wsum=%d\n", func, vn_min_rate, vn_max_rate, wsum);
|
"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_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn));
|
||||||
memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn));
|
memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn));
|
||||||
|
@ -2204,55 +2128,20 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
|
||||||
m_rs_vn.vn_counter.quota =
|
m_rs_vn.vn_counter.quota =
|
||||||
(vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8;
|
(vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8;
|
||||||
|
|
||||||
#ifdef BNX2X_PER_PROT_QOS
|
if (bp->vn_weight_sum) {
|
||||||
/* per protocol counter */
|
|
||||||
for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++) {
|
|
||||||
/* maximal Mbps for this protocol */
|
|
||||||
m_rs_vn.protocol_counters[protocol].rate =
|
|
||||||
protocol_max_rate[protocol];
|
|
||||||
/* the quota in each timer period -
|
|
||||||
number of bytes transmitted in this period */
|
|
||||||
m_rs_vn.protocol_counters[protocol].quota =
|
|
||||||
(u32)(rs_periodic_timeout_usec *
|
|
||||||
((double)m_rs_vn.
|
|
||||||
protocol_counters[protocol].rate/8));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (wsum) {
|
|
||||||
/* credit for each period of the fairness algorithm:
|
/* credit for each period of the fairness algorithm:
|
||||||
number of bytes in T_FAIR (the vn share the port rate).
|
number of bytes in T_FAIR (the vn share the port rate).
|
||||||
wsum should not be larger than 10000, thus
|
vn_weight_sum should not be larger than 10000, thus
|
||||||
T_FAIR_COEF / (8 * wsum) will always be grater than zero */
|
T_FAIR_COEF / (8 * vn_weight_sum) will always be greater
|
||||||
|
than zero */
|
||||||
m_fair_vn.vn_credit_delta =
|
m_fair_vn.vn_credit_delta =
|
||||||
max((u64)(vn_min_rate * (T_FAIR_COEF / (8 * wsum))),
|
max((u32)(vn_min_rate * (T_FAIR_COEF /
|
||||||
(u64)(m_cmng_port->fair_vars.fair_threshold * 2));
|
(8 * bp->vn_weight_sum))),
|
||||||
|
(u32)(bp->cmng.fair_vars.fair_threshold * 2));
|
||||||
DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta=%d\n",
|
DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta=%d\n",
|
||||||
m_fair_vn.vn_credit_delta);
|
m_fair_vn.vn_credit_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BNX2X_PER_PROT_QOS
|
|
||||||
do {
|
|
||||||
u32 protocolWeightSum = 0;
|
|
||||||
|
|
||||||
for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++)
|
|
||||||
protocolWeightSum +=
|
|
||||||
drvInit.protocol_min_rate[protocol];
|
|
||||||
/* per protocol counter -
|
|
||||||
NOT NEEDED IF NO PER-PROTOCOL CONGESTION MANAGEMENT */
|
|
||||||
if (protocolWeightSum > 0) {
|
|
||||||
for (protocol = 0;
|
|
||||||
protocol < NUM_OF_PROTOCOLS; protocol++)
|
|
||||||
/* credit for each period of the
|
|
||||||
fairness algorithm - number of bytes in
|
|
||||||
T_FAIR (the protocol share the vn rate) */
|
|
||||||
m_fair_vn.protocol_credit_delta[protocol] =
|
|
||||||
(u32)((vn_min_rate / 8) * t_fair *
|
|
||||||
protocol_min_rate / protocolWeightSum);
|
|
||||||
}
|
|
||||||
} while (0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Store it to internal memory */
|
/* Store it to internal memory */
|
||||||
for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++)
|
for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++)
|
||||||
REG_WR(bp, BAR_XSTRORM_INTMEM +
|
REG_WR(bp, BAR_XSTRORM_INTMEM +
|
||||||
|
@ -2265,11 +2154,10 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
|
||||||
((u32 *)(&m_fair_vn))[i]);
|
((u32 *)(&m_fair_vn))[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function is called upon link interrupt */
|
/* This function is called upon link interrupt */
|
||||||
static void bnx2x_link_attn(struct bnx2x *bp)
|
static void bnx2x_link_attn(struct bnx2x *bp)
|
||||||
{
|
{
|
||||||
int vn;
|
|
||||||
|
|
||||||
/* Make sure that we are synced with the current statistics */
|
/* Make sure that we are synced with the current statistics */
|
||||||
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
|
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
|
||||||
|
|
||||||
|
@ -2294,36 +2182,38 @@ static void bnx2x_link_attn(struct bnx2x *bp)
|
||||||
bnx2x_link_report(bp);
|
bnx2x_link_report(bp);
|
||||||
|
|
||||||
if (IS_E1HMF(bp)) {
|
if (IS_E1HMF(bp)) {
|
||||||
|
int port = BP_PORT(bp);
|
||||||
int func;
|
int func;
|
||||||
|
int vn;
|
||||||
|
|
||||||
for (vn = VN_0; vn < E1HVN_MAX; vn++) {
|
for (vn = VN_0; vn < E1HVN_MAX; vn++) {
|
||||||
if (vn == BP_E1HVN(bp))
|
if (vn == BP_E1HVN(bp))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
func = ((vn << 1) | BP_PORT(bp));
|
func = ((vn << 1) | port);
|
||||||
|
|
||||||
/* Set the attention towards other drivers
|
/* Set the attention towards other drivers
|
||||||
on the same port */
|
on the same port */
|
||||||
REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
|
REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
|
||||||
(LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
|
(LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (CHIP_IS_E1H(bp) && (bp->link_vars.line_speed > 0)) {
|
if (bp->link_vars.link_up) {
|
||||||
struct cmng_struct_per_port m_cmng_port;
|
int i;
|
||||||
u32 wsum;
|
|
||||||
int port = BP_PORT(bp);
|
/* Init rate shaping and fairness contexts */
|
||||||
|
bnx2x_init_port_minmax(bp);
|
||||||
|
|
||||||
/* Init RATE SHAPING and FAIRNESS contexts */
|
|
||||||
wsum = bnx2x_calc_vn_wsum(bp);
|
|
||||||
bnx2x_init_port_minmax(bp, (int)wsum,
|
|
||||||
bp->link_vars.line_speed,
|
|
||||||
&m_cmng_port);
|
|
||||||
if (IS_E1HMF(bp))
|
|
||||||
for (vn = VN_0; vn < E1HVN_MAX; vn++)
|
for (vn = VN_0; vn < E1HVN_MAX; vn++)
|
||||||
bnx2x_init_vn_minmax(bp, 2*vn + port,
|
bnx2x_init_vn_minmax(bp, 2*vn + port);
|
||||||
wsum, bp->link_vars.line_speed,
|
|
||||||
&m_cmng_port);
|
/* Store it to internal memory */
|
||||||
|
for (i = 0;
|
||||||
|
i < sizeof(struct cmng_struct_per_port) / 4; i++)
|
||||||
|
REG_WR(bp, BAR_XSTRORM_INTMEM +
|
||||||
|
XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4,
|
||||||
|
((u32 *)(&bp->cmng))[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4848,6 +4738,47 @@ static void bnx2x_init_internal_port(struct bnx2x *bp)
|
||||||
REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
|
REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculates the sum of vn_min_rates.
|
||||||
|
It's needed for further normalizing of the min_rates.
|
||||||
|
Returns:
|
||||||
|
sum of vn_min_rates.
|
||||||
|
or
|
||||||
|
0 - if all the min_rates are 0.
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int all_zero = 1;
|
||||||
|
int port = BP_PORT(bp);
|
||||||
|
int vn;
|
||||||
|
|
||||||
|
bp->vn_weight_sum = 0;
|
||||||
|
for (vn = VN_0; vn < E1HVN_MAX; vn++) {
|
||||||
|
int func = 2*vn + port;
|
||||||
|
u32 vn_cfg =
|
||||||
|
SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
|
||||||
|
u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
|
||||||
|
FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
|
||||||
|
|
||||||
|
/* Skip hidden vns */
|
||||||
|
if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If min rate is zero - set it to 1 */
|
||||||
|
if (!vn_min_rate)
|
||||||
|
vn_min_rate = DEF_MIN_RATE;
|
||||||
|
else
|
||||||
|
all_zero = 0;
|
||||||
|
|
||||||
|
bp->vn_weight_sum += vn_min_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ... only if all min rates are zeros - disable fairness */
|
||||||
|
if (all_zero)
|
||||||
|
bp->vn_weight_sum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void bnx2x_init_internal_func(struct bnx2x *bp)
|
static void bnx2x_init_internal_func(struct bnx2x *bp)
|
||||||
{
|
{
|
||||||
struct tstorm_eth_function_common_config tstorm_config = {0};
|
struct tstorm_eth_function_common_config tstorm_config = {0};
|
||||||
|
@ -4977,6 +4908,45 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
|
||||||
USTORM_MAX_AGG_SIZE_OFFSET(port, FP_CL_ID(fp)),
|
USTORM_MAX_AGG_SIZE_OFFSET(port, FP_CL_ID(fp)),
|
||||||
max_agg_size);
|
max_agg_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port));
|
||||||
|
|
||||||
|
/* Init rate shaping and fairness contexts */
|
||||||
|
if (IS_E1HMF(bp)) {
|
||||||
|
int vn;
|
||||||
|
|
||||||
|
/* During init there is no active link
|
||||||
|
Until link is up, set link rate to 10Gbps */
|
||||||
|
bp->link_vars.line_speed = SPEED_10000;
|
||||||
|
bnx2x_init_port_minmax(bp);
|
||||||
|
|
||||||
|
bnx2x_calc_vn_weight_sum(bp);
|
||||||
|
|
||||||
|
for (vn = VN_0; vn < E1HVN_MAX; vn++)
|
||||||
|
bnx2x_init_vn_minmax(bp, 2*vn + port);
|
||||||
|
|
||||||
|
/* Enable rate shaping and fairness */
|
||||||
|
bp->cmng.flags.cmng_enables =
|
||||||
|
CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
|
||||||
|
if (bp->vn_weight_sum)
|
||||||
|
bp->cmng.flags.cmng_enables |=
|
||||||
|
CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
|
||||||
|
else
|
||||||
|
DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
|
||||||
|
" fairness will be disabled\n");
|
||||||
|
} else {
|
||||||
|
/* rate shaping and fairness are disabled */
|
||||||
|
DP(NETIF_MSG_IFUP,
|
||||||
|
"single function mode minmax will be disabled\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Store it to internal memory */
|
||||||
|
if (bp->port.pmf)
|
||||||
|
for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
|
||||||
|
REG_WR(bp, BAR_XSTRORM_INTMEM +
|
||||||
|
XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
|
||||||
|
((u32 *)(&bp->cmng))[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
|
static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
|
||||||
|
@ -5780,22 +5750,10 @@ static int bnx2x_init_port(struct bnx2x *bp)
|
||||||
REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
|
REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
|
||||||
|
|
||||||
if (CHIP_IS_E1H(bp)) {
|
if (CHIP_IS_E1H(bp)) {
|
||||||
u32 wsum;
|
|
||||||
struct cmng_struct_per_port m_cmng_port;
|
|
||||||
int vn;
|
|
||||||
|
|
||||||
/* 0x2 disable e1hov, 0x1 enable */
|
/* 0x2 disable e1hov, 0x1 enable */
|
||||||
REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4,
|
REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4,
|
||||||
(IS_E1HMF(bp) ? 0x1 : 0x2));
|
(IS_E1HMF(bp) ? 0x1 : 0x2));
|
||||||
|
|
||||||
/* Init RATE SHAPING and FAIRNESS contexts.
|
|
||||||
Initialize as if there is 10G link. */
|
|
||||||
wsum = bnx2x_calc_vn_wsum(bp);
|
|
||||||
bnx2x_init_port_minmax(bp, (int)wsum, 10000, &m_cmng_port);
|
|
||||||
if (IS_E1HMF(bp))
|
|
||||||
for (vn = VN_0; vn < E1HVN_MAX; vn++)
|
|
||||||
bnx2x_init_vn_minmax(bp, 2*vn + port,
|
|
||||||
wsum, 10000, &m_cmng_port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Port MCP comes here */
|
/* Port MCP comes here */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче