1*d14abf15SRobert Mustacchi 
2*d14abf15SRobert Mustacchi 
3*d14abf15SRobert Mustacchi 
4*d14abf15SRobert Mustacchi 
5*d14abf15SRobert Mustacchi #include "lm5710.h"
6*d14abf15SRobert Mustacchi #include "init_defs.h"
7*d14abf15SRobert Mustacchi 
8*d14abf15SRobert Mustacchi /* Vnics per mode */
9*d14abf15SRobert Mustacchi #define ECORE_PORT2_MODE_NUM_VNICS 4
10*d14abf15SRobert Mustacchi 
11*d14abf15SRobert Mustacchi 
12*d14abf15SRobert Mustacchi /* QM queue numbers */
13*d14abf15SRobert Mustacchi #define ECORE_ETH_Q		0
14*d14abf15SRobert Mustacchi #define ECORE_TOE_Q		3
15*d14abf15SRobert Mustacchi #define ECORE_TOE_ACK_Q		6
16*d14abf15SRobert Mustacchi #define ECORE_ISCSI_Q		9
17*d14abf15SRobert Mustacchi #define ECORE_ISCSI_ACK_Q	11
18*d14abf15SRobert Mustacchi #define ECORE_FCOE_Q		10
19*d14abf15SRobert Mustacchi 
20*d14abf15SRobert Mustacchi /* Vnics per mode */
21*d14abf15SRobert Mustacchi #define ECORE_PORT4_MODE_NUM_VNICS 2
22*d14abf15SRobert Mustacchi 
23*d14abf15SRobert Mustacchi /* COS offset for port1 in E3 B0 4port mode */
24*d14abf15SRobert Mustacchi #define ECORE_E3B0_PORT1_COS_OFFSET 3
25*d14abf15SRobert Mustacchi 
26*d14abf15SRobert Mustacchi /* QM Register addresses */
27*d14abf15SRobert Mustacchi #define ECORE_Q_VOQ_REG_ADDR(pf_q_num)\
28*d14abf15SRobert Mustacchi 	(QM_REG_QVOQIDX_0 + 4 * (pf_q_num))
29*d14abf15SRobert Mustacchi #define ECORE_VOQ_Q_REG_ADDR(cos, pf_q_num)\
30*d14abf15SRobert Mustacchi 	(QM_REG_VOQQMASK_0_LSB + 4 * ((cos) * 2 + ((pf_q_num) >> 5)))
31*d14abf15SRobert Mustacchi #define ECORE_Q_CMDQ_REG_ADDR(pf_q_num)\
32*d14abf15SRobert Mustacchi 	(QM_REG_BYTECRDCMDQ_0 + 4 * ((pf_q_num) >> 4))
33*d14abf15SRobert Mustacchi 
34*d14abf15SRobert Mustacchi /* extracts the QM queue number for the specified port and vnic */
35*d14abf15SRobert Mustacchi #define ECORE_PF_Q_NUM(q_num, port, vnic)\
36*d14abf15SRobert Mustacchi 	((((port) << 1) | (vnic)) * 16 + (q_num))
37*d14abf15SRobert Mustacchi 
38*d14abf15SRobert Mustacchi 
39*d14abf15SRobert Mustacchi /* Maps the specified queue to the specified COS */
ecore_map_q_cos(struct _lm_device_t * pdev,u32_t q_num,u32_t new_cos)40*d14abf15SRobert Mustacchi void ecore_map_q_cos(struct _lm_device_t *pdev, u32_t q_num, u32_t new_cos)
41*d14abf15SRobert Mustacchi {
42*d14abf15SRobert Mustacchi 	/* find current COS mapping */
43*d14abf15SRobert Mustacchi 	u32_t curr_cos = REG_RD(pdev, QM_REG_QVOQIDX_0 + q_num * 4);
44*d14abf15SRobert Mustacchi 
45*d14abf15SRobert Mustacchi 	/* check if queue->COS mapping has changed */
46*d14abf15SRobert Mustacchi 	if (curr_cos != new_cos) {
47*d14abf15SRobert Mustacchi 		u32_t num_vnics = ECORE_PORT2_MODE_NUM_VNICS;
48*d14abf15SRobert Mustacchi 		u32_t reg_addr, reg_bit_map, vnic;
49*d14abf15SRobert Mustacchi 
50*d14abf15SRobert Mustacchi 		/* update parameters for 4port mode */
51*d14abf15SRobert Mustacchi 		if (INIT_MODE_FLAGS(pdev) & MODE_PORT4) {
52*d14abf15SRobert Mustacchi 			num_vnics = ECORE_PORT4_MODE_NUM_VNICS;
53*d14abf15SRobert Mustacchi 			if (PORT_ID(pdev)) {
54*d14abf15SRobert Mustacchi 				curr_cos += ECORE_E3B0_PORT1_COS_OFFSET;
55*d14abf15SRobert Mustacchi 				new_cos += ECORE_E3B0_PORT1_COS_OFFSET;
56*d14abf15SRobert Mustacchi 			}
57*d14abf15SRobert Mustacchi 		}
58*d14abf15SRobert Mustacchi 
59*d14abf15SRobert Mustacchi 		/* change queue mapping for each VNIC */
60*d14abf15SRobert Mustacchi 		for (vnic = 0; vnic < num_vnics; vnic++) {
61*d14abf15SRobert Mustacchi 			u32_t pf_q_num =
62*d14abf15SRobert Mustacchi 				ECORE_PF_Q_NUM(q_num, PORT_ID(pdev), vnic);
63*d14abf15SRobert Mustacchi 			u32_t q_bit_map = 1 << (pf_q_num & 0x1f);
64*d14abf15SRobert Mustacchi 
65*d14abf15SRobert Mustacchi 			/* overwrite queue->VOQ mapping */
66*d14abf15SRobert Mustacchi 			REG_WR(pdev, ECORE_Q_VOQ_REG_ADDR(pf_q_num), new_cos);
67*d14abf15SRobert Mustacchi 
68*d14abf15SRobert Mustacchi 			/* clear queue bit from current COS bit map */
69*d14abf15SRobert Mustacchi 			reg_addr = ECORE_VOQ_Q_REG_ADDR(curr_cos, pf_q_num);
70*d14abf15SRobert Mustacchi 			reg_bit_map = REG_RD(pdev, reg_addr);
71*d14abf15SRobert Mustacchi 			REG_WR(pdev, reg_addr, reg_bit_map & (~q_bit_map));
72*d14abf15SRobert Mustacchi 
73*d14abf15SRobert Mustacchi 			/* set queue bit in new COS bit map */
74*d14abf15SRobert Mustacchi 			reg_addr = ECORE_VOQ_Q_REG_ADDR(new_cos, pf_q_num);
75*d14abf15SRobert Mustacchi 			reg_bit_map = REG_RD(pdev, reg_addr);
76*d14abf15SRobert Mustacchi 			REG_WR(pdev, reg_addr, reg_bit_map | q_bit_map);
77*d14abf15SRobert Mustacchi 
78*d14abf15SRobert Mustacchi 			/* set/clear queue bit in command-queue bit map
79*d14abf15SRobert Mustacchi 			(E2/E3A0 only, valid COS values are 0/1) */
80*d14abf15SRobert Mustacchi 			if (!(INIT_MODE_FLAGS(pdev) & MODE_E3_B0)) {
81*d14abf15SRobert Mustacchi 				reg_addr = ECORE_Q_CMDQ_REG_ADDR(pf_q_num);
82*d14abf15SRobert Mustacchi 				reg_bit_map = REG_RD(pdev, reg_addr);
83*d14abf15SRobert Mustacchi 				q_bit_map = 1 << (2 * (pf_q_num & 0xf));
84*d14abf15SRobert Mustacchi 				reg_bit_map = new_cos ?
85*d14abf15SRobert Mustacchi 					      (reg_bit_map | q_bit_map) :
86*d14abf15SRobert Mustacchi 					      (reg_bit_map & (~q_bit_map));
87*d14abf15SRobert Mustacchi 				REG_WR(pdev, reg_addr, reg_bit_map);
88*d14abf15SRobert Mustacchi 			}
89*d14abf15SRobert Mustacchi 		}
90*d14abf15SRobert Mustacchi 	}
91*d14abf15SRobert Mustacchi }
92*d14abf15SRobert Mustacchi 
93*d14abf15SRobert Mustacchi /* Configures the QM according to the specified per-traffic-type COSes */
ecore_dcb_config_qm(struct _lm_device_t * pdev,enum cos_mode mode,struct priority_cos * traffic_cos)94*d14abf15SRobert Mustacchi void ecore_dcb_config_qm(struct _lm_device_t *pdev, enum cos_mode mode,
95*d14abf15SRobert Mustacchi 				       struct priority_cos *traffic_cos)
96*d14abf15SRobert Mustacchi {
97*d14abf15SRobert Mustacchi 	ecore_map_q_cos(pdev, ECORE_FCOE_Q,
98*d14abf15SRobert Mustacchi 			traffic_cos[LLFC_TRAFFIC_TYPE_FCOE].cos);
99*d14abf15SRobert Mustacchi 	ecore_map_q_cos(pdev, ECORE_ISCSI_Q,
100*d14abf15SRobert Mustacchi 			traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
101*d14abf15SRobert Mustacchi 	ecore_map_q_cos(pdev, ECORE_ISCSI_ACK_Q,
102*d14abf15SRobert Mustacchi 		traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
103*d14abf15SRobert Mustacchi 	if (mode != STATIC_COS) {
104*d14abf15SRobert Mustacchi 		/* required only in OVERRIDE_COS mode */
105*d14abf15SRobert Mustacchi 		ecore_map_q_cos(pdev, ECORE_ETH_Q,
106*d14abf15SRobert Mustacchi 				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
107*d14abf15SRobert Mustacchi 		ecore_map_q_cos(pdev, ECORE_TOE_Q,
108*d14abf15SRobert Mustacchi 				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
109*d14abf15SRobert Mustacchi 		ecore_map_q_cos(pdev, ECORE_TOE_ACK_Q,
110*d14abf15SRobert Mustacchi 				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
111*d14abf15SRobert Mustacchi 	}
112*d14abf15SRobert Mustacchi }
113*d14abf15SRobert Mustacchi 
114*d14abf15SRobert Mustacchi 
115*d14abf15SRobert Mustacchi /*
116*d14abf15SRobert Mustacchi  * congestion managment port init api description
117*d14abf15SRobert Mustacchi  * the api works as follows:
118*d14abf15SRobert Mustacchi  * the driver should pass the cmng_init_input struct, the port_init function
119*d14abf15SRobert Mustacchi  * will prepare the required internal ram structure which will be passed back
120*d14abf15SRobert Mustacchi  * to the driver (cmng_init) that will write it into the internal ram.
121*d14abf15SRobert Mustacchi  *
122*d14abf15SRobert Mustacchi  * IMPORTANT REMARKS:
123*d14abf15SRobert Mustacchi  * 1. the cmng_init struct does not represent the contiguous internal ram
124*d14abf15SRobert Mustacchi  *    structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET
125*d14abf15SRobert Mustacchi  *    offset in order to write the port sub struct and the
126*d14abf15SRobert Mustacchi  *    PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other
127*d14abf15SRobert Mustacchi  *    words - don't use memcpy!).
128*d14abf15SRobert Mustacchi  * 2. although the cmng_init struct is filled for the maximal vnic number
129*d14abf15SRobert Mustacchi  *    possible, the driver should only write the valid vnics into the internal
130*d14abf15SRobert Mustacchi  *    ram according to the appropriate port mode.
131*d14abf15SRobert Mustacchi  */
132*d14abf15SRobert Mustacchi #define BITS_TO_BYTES(x) ((x)/8)
133*d14abf15SRobert Mustacchi 
134*d14abf15SRobert Mustacchi /* CMNG constants, as derived from system spec calculations */
135*d14abf15SRobert Mustacchi 
136*d14abf15SRobert Mustacchi /* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */
137*d14abf15SRobert Mustacchi #define DEF_MIN_RATE 100
138*d14abf15SRobert Mustacchi 
139*d14abf15SRobert Mustacchi /* resolution of the rate shaping timer - 400 usec */
140*d14abf15SRobert Mustacchi #define RS_PERIODIC_TIMEOUT_USEC 400
141*d14abf15SRobert Mustacchi 
142*d14abf15SRobert Mustacchi /*
143*d14abf15SRobert Mustacchi  *  number of bytes in single QM arbitration cycle -
144*d14abf15SRobert Mustacchi  *  coefficient for calculating the fairness timer
145*d14abf15SRobert Mustacchi  */
146*d14abf15SRobert Mustacchi #define QM_ARB_BYTES 160000
147*d14abf15SRobert Mustacchi 
148*d14abf15SRobert Mustacchi /* resolution of Min algorithm 1:100 */
149*d14abf15SRobert Mustacchi #define MIN_RES 100
150*d14abf15SRobert Mustacchi 
151*d14abf15SRobert Mustacchi /*
152*d14abf15SRobert Mustacchi  *  how many bytes above threshold for
153*d14abf15SRobert Mustacchi  *  the minimal credit of Min algorithm
154*d14abf15SRobert Mustacchi  */
155*d14abf15SRobert Mustacchi #define MIN_ABOVE_THRESH 32768
156*d14abf15SRobert Mustacchi 
157*d14abf15SRobert Mustacchi /*
158*d14abf15SRobert Mustacchi  *  Fairness algorithm integration time coefficient -
159*d14abf15SRobert Mustacchi  *  for calculating the actual Tfair
160*d14abf15SRobert Mustacchi  */
161*d14abf15SRobert Mustacchi #define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES)
162*d14abf15SRobert Mustacchi 
163*d14abf15SRobert Mustacchi /* Memory of fairness algorithm - 2 cycles */
164*d14abf15SRobert Mustacchi #define FAIR_MEM 2
165*d14abf15SRobert Mustacchi #define SAFC_TIMEOUT_USEC 52
166*d14abf15SRobert Mustacchi 
167*d14abf15SRobert Mustacchi #define SDM_TICKS 4
168*d14abf15SRobert Mustacchi 
169*d14abf15SRobert Mustacchi 
ecore_init_max(const struct cmng_init_input * input_data,u32_t r_param,struct cmng_init * ram_data)170*d14abf15SRobert Mustacchi void ecore_init_max(const struct cmng_init_input *input_data,
171*d14abf15SRobert Mustacchi 				  u32_t r_param, struct cmng_init *ram_data)
172*d14abf15SRobert Mustacchi {
173*d14abf15SRobert Mustacchi 	u32_t vnic;
174*d14abf15SRobert Mustacchi 	struct cmng_vnic *vdata = &ram_data->vnic;
175*d14abf15SRobert Mustacchi 	struct cmng_struct_per_port *pdata = &ram_data->port;
176*d14abf15SRobert Mustacchi 	/*
177*d14abf15SRobert Mustacchi 	 * rate shaping per-port variables
178*d14abf15SRobert Mustacchi 	 *  100 micro seconds in SDM ticks = 25
179*d14abf15SRobert Mustacchi 	 *  since each tick is 4 microSeconds
180*d14abf15SRobert Mustacchi 	 */
181*d14abf15SRobert Mustacchi 
182*d14abf15SRobert Mustacchi 	pdata->rs_vars.rs_periodic_timeout =
183*d14abf15SRobert Mustacchi 	RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS;
184*d14abf15SRobert Mustacchi 
185*d14abf15SRobert Mustacchi 	/* this is the threshold below which no timer arming will occur.
186*d14abf15SRobert Mustacchi 	 *  1.25 coefficient is for the threshold to be a little bigger
187*d14abf15SRobert Mustacchi 	 *  then the real time to compensate for timer in-accuracy
188*d14abf15SRobert Mustacchi 	 */
189*d14abf15SRobert Mustacchi 	pdata->rs_vars.rs_threshold =
190*d14abf15SRobert Mustacchi 	(5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4;
191*d14abf15SRobert Mustacchi 
192*d14abf15SRobert Mustacchi 	/* rate shaping per-vnic variables */
193*d14abf15SRobert Mustacchi 	for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
194*d14abf15SRobert Mustacchi 		/* global vnic counter */
195*d14abf15SRobert Mustacchi 		vdata->vnic_max_rate[vnic].vn_counter.rate =
196*d14abf15SRobert Mustacchi 		input_data->vnic_max_rate[vnic];
197*d14abf15SRobert Mustacchi 		/*
198*d14abf15SRobert Mustacchi 		 * maximal Mbps for this vnic
199*d14abf15SRobert Mustacchi 		 * the quota in each timer period - number of bytes
200*d14abf15SRobert Mustacchi 		 * transmitted in this period
201*d14abf15SRobert Mustacchi 		 */
202*d14abf15SRobert Mustacchi 		vdata->vnic_max_rate[vnic].vn_counter.quota =
203*d14abf15SRobert Mustacchi 			RS_PERIODIC_TIMEOUT_USEC *
204*d14abf15SRobert Mustacchi 			(u32_t)vdata->vnic_max_rate[vnic].vn_counter.rate / 8;
205*d14abf15SRobert Mustacchi 	}
206*d14abf15SRobert Mustacchi 
207*d14abf15SRobert Mustacchi }
208*d14abf15SRobert Mustacchi 
ecore_init_max_per_vn(u16_t vnic_max_rate,struct rate_shaping_vars_per_vn * ram_data)209*d14abf15SRobert Mustacchi void ecore_init_max_per_vn(u16_t vnic_max_rate,
210*d14abf15SRobert Mustacchi 				  struct rate_shaping_vars_per_vn *ram_data)
211*d14abf15SRobert Mustacchi {
212*d14abf15SRobert Mustacchi 	/* global vnic counter */
213*d14abf15SRobert Mustacchi 	ram_data->vn_counter.rate = vnic_max_rate;
214*d14abf15SRobert Mustacchi 
215*d14abf15SRobert Mustacchi 	/*
216*d14abf15SRobert Mustacchi 	* maximal Mbps for this vnic
217*d14abf15SRobert Mustacchi 	* the quota in each timer period - number of bytes
218*d14abf15SRobert Mustacchi 	* transmitted in this period
219*d14abf15SRobert Mustacchi 	*/
220*d14abf15SRobert Mustacchi 	ram_data->vn_counter.quota =
221*d14abf15SRobert Mustacchi 		RS_PERIODIC_TIMEOUT_USEC * (u32_t)vnic_max_rate / 8;
222*d14abf15SRobert Mustacchi }
223*d14abf15SRobert Mustacchi 
ecore_init_min(const struct cmng_init_input * input_data,u32_t r_param,struct cmng_init * ram_data)224*d14abf15SRobert Mustacchi void ecore_init_min(const struct cmng_init_input *input_data,
225*d14abf15SRobert Mustacchi 				  u32_t r_param, struct cmng_init *ram_data)
226*d14abf15SRobert Mustacchi {
227*d14abf15SRobert Mustacchi 	u32_t vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair;
228*d14abf15SRobert Mustacchi 	struct cmng_vnic *vdata = &ram_data->vnic;
229*d14abf15SRobert Mustacchi 	struct cmng_struct_per_port *pdata = &ram_data->port;
230*d14abf15SRobert Mustacchi 
231*d14abf15SRobert Mustacchi 	/* this is the resolution of the fairness timer */
232*d14abf15SRobert Mustacchi 	fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
233*d14abf15SRobert Mustacchi 
234*d14abf15SRobert Mustacchi 	/*
235*d14abf15SRobert Mustacchi 	 * fairness per-port variables
236*d14abf15SRobert Mustacchi 	 * for 10G it is 1000usec. for 1G it is 10000usec.
237*d14abf15SRobert Mustacchi 	 */
238*d14abf15SRobert Mustacchi 	tFair = T_FAIR_COEF / input_data->port_rate;
239*d14abf15SRobert Mustacchi 
240*d14abf15SRobert Mustacchi 	/* this is the threshold below which we won't arm the timer anymore */
241*d14abf15SRobert Mustacchi 	pdata->fair_vars.fair_threshold = QM_ARB_BYTES;
242*d14abf15SRobert Mustacchi 
243*d14abf15SRobert Mustacchi 	/*
244*d14abf15SRobert Mustacchi 	 *  we multiply by 1e3/8 to get bytes/msec. We don't want the credits
245*d14abf15SRobert Mustacchi 	 *  to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution)
246*d14abf15SRobert Mustacchi 	 */
247*d14abf15SRobert Mustacchi 	pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM;
248*d14abf15SRobert Mustacchi 
249*d14abf15SRobert Mustacchi 	/* since each tick is 4 microSeconds */
250*d14abf15SRobert Mustacchi 	pdata->fair_vars.fairness_timeout =
251*d14abf15SRobert Mustacchi 				fair_periodic_timeout_usec / SDM_TICKS;
252*d14abf15SRobert Mustacchi 
253*d14abf15SRobert Mustacchi 	/* calculate sum of weights */
254*d14abf15SRobert Mustacchi 	vnicWeightSum = 0;
255*d14abf15SRobert Mustacchi 
256*d14abf15SRobert Mustacchi 	for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++)
257*d14abf15SRobert Mustacchi 		vnicWeightSum += input_data->vnic_min_rate[vnic];
258*d14abf15SRobert Mustacchi 
259*d14abf15SRobert Mustacchi 	/* global vnic counter */
260*d14abf15SRobert Mustacchi 	if (vnicWeightSum > 0) {
261*d14abf15SRobert Mustacchi 		/* fairness per-vnic variables */
262*d14abf15SRobert Mustacchi 		for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
263*d14abf15SRobert Mustacchi 			/*
264*d14abf15SRobert Mustacchi 			 *  this is the credit for each period of the fairness
265*d14abf15SRobert Mustacchi 			 *  algorithm - number of bytes in T_FAIR (this vnic
266*d14abf15SRobert Mustacchi 			 *  share of the port rate)
267*d14abf15SRobert Mustacchi 			 */
268*d14abf15SRobert Mustacchi 			vdata->vnic_min_rate[vnic].vn_credit_delta =
269*d14abf15SRobert Mustacchi 				((u32_t)(input_data->vnic_min_rate[vnic]) * 100 *
270*d14abf15SRobert Mustacchi 				(T_FAIR_COEF / (8 * 100 * vnicWeightSum)));
271*d14abf15SRobert Mustacchi 			if (vdata->vnic_min_rate[vnic].vn_credit_delta <
272*d14abf15SRobert Mustacchi 			    pdata->fair_vars.fair_threshold +
273*d14abf15SRobert Mustacchi 			    MIN_ABOVE_THRESH) {
274*d14abf15SRobert Mustacchi 				vdata->vnic_min_rate[vnic].vn_credit_delta =
275*d14abf15SRobert Mustacchi 					pdata->fair_vars.fair_threshold +
276*d14abf15SRobert Mustacchi 					MIN_ABOVE_THRESH;
277*d14abf15SRobert Mustacchi 			}
278*d14abf15SRobert Mustacchi 		}
279*d14abf15SRobert Mustacchi 	}
280*d14abf15SRobert Mustacchi }
281*d14abf15SRobert Mustacchi 
ecore_init_fw_wrr(const struct cmng_init_input * input_data,u32_t r_param,struct cmng_init * ram_data)282*d14abf15SRobert Mustacchi void ecore_init_fw_wrr(const struct cmng_init_input *input_data,
283*d14abf15SRobert Mustacchi 				     u32_t r_param, struct cmng_init *ram_data)
284*d14abf15SRobert Mustacchi {
285*d14abf15SRobert Mustacchi 	u32_t vnic, cos;
286*d14abf15SRobert Mustacchi 	u32_t cosWeightSum = 0;
287*d14abf15SRobert Mustacchi 	struct cmng_vnic *vdata = &ram_data->vnic;
288*d14abf15SRobert Mustacchi 	struct cmng_struct_per_port *pdata = &ram_data->port;
289*d14abf15SRobert Mustacchi 
290*d14abf15SRobert Mustacchi 	for (cos = 0; cos < MAX_COS_NUMBER; cos++)
291*d14abf15SRobert Mustacchi 		cosWeightSum += input_data->cos_min_rate[cos];
292*d14abf15SRobert Mustacchi 
293*d14abf15SRobert Mustacchi 	if (cosWeightSum > 0) {
294*d14abf15SRobert Mustacchi 
295*d14abf15SRobert Mustacchi 		for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
296*d14abf15SRobert Mustacchi 			/*
297*d14abf15SRobert Mustacchi 			 *  Since cos and vnic shouldn't work together the rate
298*d14abf15SRobert Mustacchi 			 *  to divide between the coses is the port rate.
299*d14abf15SRobert Mustacchi 			 */
300*d14abf15SRobert Mustacchi 			u32_t *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta;
301*d14abf15SRobert Mustacchi 			for (cos = 0; cos < MAX_COS_NUMBER; cos++) {
302*d14abf15SRobert Mustacchi 				/*
303*d14abf15SRobert Mustacchi 				 * this is the credit for each period of
304*d14abf15SRobert Mustacchi 				 * the fairness algorithm - number of bytes
305*d14abf15SRobert Mustacchi 				 * in T_FAIR (this cos share of the vnic rate)
306*d14abf15SRobert Mustacchi 				 */
307*d14abf15SRobert Mustacchi 				ccd[cos] =
308*d14abf15SRobert Mustacchi 				    ((u32_t)input_data->cos_min_rate[cos] * 100 *
309*d14abf15SRobert Mustacchi 				    (T_FAIR_COEF / (8 * 100 * cosWeightSum)));
310*d14abf15SRobert Mustacchi 				 if (ccd[cos] < pdata->fair_vars.fair_threshold
311*d14abf15SRobert Mustacchi 						+ MIN_ABOVE_THRESH) {
312*d14abf15SRobert Mustacchi 					ccd[cos] =
313*d14abf15SRobert Mustacchi 					    pdata->fair_vars.fair_threshold +
314*d14abf15SRobert Mustacchi 					    MIN_ABOVE_THRESH;
315*d14abf15SRobert Mustacchi 				}
316*d14abf15SRobert Mustacchi 			}
317*d14abf15SRobert Mustacchi 		}
318*d14abf15SRobert Mustacchi 	}
319*d14abf15SRobert Mustacchi }
320*d14abf15SRobert Mustacchi 
ecore_init_safc(const struct cmng_init_input * input_data,struct cmng_init * ram_data)321*d14abf15SRobert Mustacchi void ecore_init_safc(const struct cmng_init_input *input_data,
322*d14abf15SRobert Mustacchi 				   struct cmng_init *ram_data)
323*d14abf15SRobert Mustacchi {
324*d14abf15SRobert Mustacchi 	/* in microSeconds */
325*d14abf15SRobert Mustacchi 	ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC;
326*d14abf15SRobert Mustacchi }
327*d14abf15SRobert Mustacchi 
328*d14abf15SRobert Mustacchi /* Congestion management port init */
ecore_init_cmng(const struct cmng_init_input * input_data,struct cmng_init * ram_data)329*d14abf15SRobert Mustacchi void ecore_init_cmng(const struct cmng_init_input *input_data,
330*d14abf15SRobert Mustacchi 				   struct cmng_init *ram_data)
331*d14abf15SRobert Mustacchi {
332*d14abf15SRobert Mustacchi 	u32_t r_param;
333*d14abf15SRobert Mustacchi 	mm_mem_zero(ram_data,sizeof(struct cmng_init));
334*d14abf15SRobert Mustacchi 
335*d14abf15SRobert Mustacchi 	ram_data->port.flags = input_data->flags;
336*d14abf15SRobert Mustacchi 
337*d14abf15SRobert Mustacchi 	/*
338*d14abf15SRobert Mustacchi 	 *  number of bytes transmitted in a rate of 10Gbps
339*d14abf15SRobert Mustacchi 	 *  in one usec = 1.25KB.
340*d14abf15SRobert Mustacchi 	 */
341*d14abf15SRobert Mustacchi 	r_param = BITS_TO_BYTES(input_data->port_rate);
342*d14abf15SRobert Mustacchi 	ecore_init_max(input_data, r_param, ram_data);
343*d14abf15SRobert Mustacchi 	ecore_init_min(input_data, r_param, ram_data);
344*d14abf15SRobert Mustacchi 	ecore_init_fw_wrr(input_data, r_param, ram_data);
345*d14abf15SRobert Mustacchi 	ecore_init_safc(input_data, ram_data);
346*d14abf15SRobert Mustacchi }
347*d14abf15SRobert Mustacchi 
348