diff options
author | Yuval Mintz <yuvalmin@broadcom.com> | 2012-04-03 14:41:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-04-04 01:37:59 -0400 |
commit | b475d78f464195cbdeeda0d80a2ffbd54653a4bd (patch) | |
tree | 716c06b09bf324df76ae35660efeb0040a810096 /drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h | |
parent | 7e8e02df17106007f4b043a39d22682f74df6f6f (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.h | 217 |
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 | |||
332 | static 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 | |||
369 | static 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 | |||
424 | static 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 | |||
461 | static 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 */ | ||
469 | static 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 | */ | ||
505 | static inline void bnx2x_clear_blocks_parity(struct bnx2x *bp) | 712 | static inline void bnx2x_clear_blocks_parity(struct bnx2x *bp) |
506 | { | 713 | { |
507 | int i; | 714 | int i; |