aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
diff options
context:
space:
mode:
authorYuval Mintz <yuvalmin@broadcom.com>2012-04-03 14:41:29 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-04 01:37:59 -0400
commitb475d78f464195cbdeeda0d80a2ffbd54653a4bd (patch)
tree716c06b09bf324df76ae35660efeb0040a810096 /drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
parent7e8e02df17106007f4b043a39d22682f74df6f6f (diff)
bnx2x: congestion management re-organization
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>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h217
1 files changed, 212 insertions, 5 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
index 29f5c3cca31a..e6bb9f4c619c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
@@ -241,7 +241,8 @@ static inline void bnx2x_map_q_cos(struct bnx2x *bp, u32 q_num, u32 new_cos)
241 REG_WR(bp, reg_addr, reg_bit_map | q_bit_map); 241 REG_WR(bp, reg_addr, reg_bit_map | q_bit_map);
242 242
243 /* set/clear queue bit in command-queue bit map 243 /* set/clear queue bit in command-queue bit map
244 (E2/E3A0 only, valid COS values are 0/1) */ 244 * (E2/E3A0 only, valid COS values are 0/1)
245 */
245 if (!(INIT_MODE_FLAGS(bp) & MODE_E3_B0)) { 246 if (!(INIT_MODE_FLAGS(bp) & MODE_E3_B0)) {
246 reg_addr = BNX2X_Q_CMDQ_REG_ADDR(pf_q_num); 247 reg_addr = BNX2X_Q_CMDQ_REG_ADDR(pf_q_num);
247 reg_bit_map = REG_RD(bp, reg_addr); 248 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,
277} 278}
278 279
279 280
280/* Returns the index of start or end of a specific block stage in ops array*/ 281/* congestion managment port init api description
282 * the api works as follows:
283 * the driver should pass the cmng_init_input struct, the port_init function
284 * will prepare the required internal ram structure which will be passed back
285 * to the driver (cmng_init) that will write it into the internal ram.
286 *
287 * IMPORTANT REMARKS:
288 * 1. the cmng_init struct does not represent the contiguous internal ram
289 * structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET
290 * offset in order to write the port sub struct and the
291 * PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other
292 * words - don't use memcpy!).
293 * 2. although the cmng_init struct is filled for the maximal vnic number
294 * possible, the driver should only write the valid vnics into the internal
295 * ram according to the appropriate port mode.
296 */
297#define BITS_TO_BYTES(x) ((x)/8)
298
299/* CMNG constants, as derived from system spec calculations */
300
301/* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */
302#define DEF_MIN_RATE 100
303
304/* resolution of the rate shaping timer - 400 usec */
305#define RS_PERIODIC_TIMEOUT_USEC 400
306
307/* number of bytes in single QM arbitration cycle -
308 * coefficient for calculating the fairness timer
309 */
310#define QM_ARB_BYTES 160000
311
312/* resolution of Min algorithm 1:100 */
313#define MIN_RES 100
314
315/* how many bytes above threshold for
316 * the minimal credit of Min algorithm
317 */
318#define MIN_ABOVE_THRESH 32768
319
320/* Fairness algorithm integration time coefficient -
321 * for calculating the actual Tfair
322 */
323#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES)
324
325/* Memory of fairness algorithm - 2 cycles */
326#define FAIR_MEM 2
327#define SAFC_TIMEOUT_USEC 52
328
329#define SDM_TICKS 4
330
331
332static inline void bnx2x_init_max(const struct cmng_init_input *input_data,
333 u32 r_param, struct cmng_init *ram_data)
334{
335 u32 vnic;
336 struct cmng_vnic *vdata = &ram_data->vnic;
337 struct cmng_struct_per_port *pdata = &ram_data->port;
338 /* rate shaping per-port variables
339 * 100 micro seconds in SDM ticks = 25
340 * since each tick is 4 microSeconds
341 */
342
343 pdata->rs_vars.rs_periodic_timeout =
344 RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS;
345
346 /* this is the threshold below which no timer arming will occur.
347 * 1.25 coefficient is for the threshold to be a little bigger
348 * then the real time to compensate for timer in-accuracy
349 */
350 pdata->rs_vars.rs_threshold =
351 (5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4;
352
353 /* rate shaping per-vnic variables */
354 for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
355 /* global vnic counter */
356 vdata->vnic_max_rate[vnic].vn_counter.rate =
357 input_data->vnic_max_rate[vnic];
358 /* maximal Mbps for this vnic
359 * the quota in each timer period - number of bytes
360 * transmitted in this period
361 */
362 vdata->vnic_max_rate[vnic].vn_counter.quota =
363 RS_PERIODIC_TIMEOUT_USEC *
364 (u32)vdata->vnic_max_rate[vnic].vn_counter.rate / 8;
365 }
366
367}
368
369static inline void bnx2x_init_min(const struct cmng_init_input *input_data,
370 u32 r_param, struct cmng_init *ram_data)
371{
372 u32 vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair;
373 struct cmng_vnic *vdata = &ram_data->vnic;
374 struct cmng_struct_per_port *pdata = &ram_data->port;
375
376 /* this is the resolution of the fairness timer */
377 fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
378
379 /* fairness per-port variables
380 * for 10G it is 1000usec. for 1G it is 10000usec.
381 */
382 tFair = T_FAIR_COEF / input_data->port_rate;
383
384 /* this is the threshold below which we won't arm the timer anymore */
385 pdata->fair_vars.fair_threshold = QM_ARB_BYTES;
386
387 /* we multiply by 1e3/8 to get bytes/msec. We don't want the credits
388 * to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution)
389 */
390 pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM;
391
392 /* since each tick is 4 microSeconds */
393 pdata->fair_vars.fairness_timeout =
394 fair_periodic_timeout_usec / SDM_TICKS;
395
396 /* calculate sum of weights */
397 vnicWeightSum = 0;
398
399 for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++)
400 vnicWeightSum += input_data->vnic_min_rate[vnic];
401
402 /* global vnic counter */
403 if (vnicWeightSum > 0) {
404 /* fairness per-vnic variables */
405 for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
406 /* this is the credit for each period of the fairness
407 * algorithm - number of bytes in T_FAIR (this vnic
408 * share of the port rate)
409 */
410 vdata->vnic_min_rate[vnic].vn_credit_delta =
411 (u32)input_data->vnic_min_rate[vnic] * 100 *
412 T_FAIR_COEF / (8 * 100 * vnicWeightSum);
413 if (vdata->vnic_min_rate[vnic].vn_credit_delta <
414 pdata->fair_vars.fair_threshold +
415 MIN_ABOVE_THRESH) {
416 vdata->vnic_min_rate[vnic].vn_credit_delta =
417 pdata->fair_vars.fair_threshold +
418 MIN_ABOVE_THRESH;
419 }
420 }
421 }
422}
423
424static inline void bnx2x_init_fw_wrr(const struct cmng_init_input *input_data,
425 u32 r_param, struct cmng_init *ram_data)
426{
427 u32 vnic, cos;
428 u32 cosWeightSum = 0;
429 struct cmng_vnic *vdata = &ram_data->vnic;
430 struct cmng_struct_per_port *pdata = &ram_data->port;
431
432 for (cos = 0; cos < MAX_COS_NUMBER; cos++)
433 cosWeightSum += input_data->cos_min_rate[cos];
434
435 if (cosWeightSum > 0) {
436
437 for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
438 /* Since cos and vnic shouldn't work together the rate
439 * to divide between the coses is the port rate.
440 */
441 u32 *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta;
442 for (cos = 0; cos < MAX_COS_NUMBER; cos++) {
443 /* this is the credit for each period of
444 * the fairness algorithm - number of bytes
445 * in T_FAIR (this cos share of the vnic rate)
446 */
447 ccd[cos] =
448 (u32)input_data->cos_min_rate[cos] * 100 *
449 T_FAIR_COEF / (8 * 100 * cosWeightSum);
450 if (ccd[cos] < pdata->fair_vars.fair_threshold
451 + MIN_ABOVE_THRESH) {
452 ccd[cos] =
453 pdata->fair_vars.fair_threshold +
454 MIN_ABOVE_THRESH;
455 }
456 }
457 }
458 }
459}
460
461static inline void bnx2x_init_safc(const struct cmng_init_input *input_data,
462 struct cmng_init *ram_data)
463{
464 /* in microSeconds */
465 ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC;
466}
467
468/* Congestion management port init */
469static inline void bnx2x_init_cmng(const struct cmng_init_input *input_data,
470 struct cmng_init *ram_data)
471{
472 u32 r_param;
473 memset(ram_data, 0, sizeof(struct cmng_init));
474
475 ram_data->port.flags = input_data->flags;
476
477 /* number of bytes transmitted in a rate of 10Gbps
478 * in one usec = 1.25KB.
479 */
480 r_param = BITS_TO_BYTES(input_data->port_rate);
481 bnx2x_init_max(input_data, r_param, ram_data);
482 bnx2x_init_min(input_data, r_param, ram_data);
483 bnx2x_init_fw_wrr(input_data, r_param, ram_data);
484 bnx2x_init_safc(input_data, ram_data);
485}
486
487
488
489/* Returns the index of start or end of a specific block stage in ops array */
281#define BLOCK_OPS_IDX(block, stage, end) \ 490#define BLOCK_OPS_IDX(block, stage, end) \
282 (2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end)) 491 (2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
283 492
@@ -499,9 +708,7 @@ static inline void bnx2x_disable_blocks_parity(struct bnx2x *bp)
499 bnx2x_set_mcp_parity(bp, false); 708 bnx2x_set_mcp_parity(bp, false);
500} 709}
501 710
502/** 711/* Clear the parity error status registers. */
503 * Clear the parity error status registers.
504 */
505static inline void bnx2x_clear_blocks_parity(struct bnx2x *bp) 712static inline void bnx2x_clear_blocks_parity(struct bnx2x *bp)
506{ 713{
507 int i; 714 int i;