diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-08-12 04:23:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-08-13 02:02:38 -0400 |
commit | 6fe49bb978de3de0ba7ff9d6b2d55a15518db2a3 (patch) | |
tree | ad6e21f76c6d166697dbd7e6605ffc12b91b419f /drivers/net/bnx2x_main.c | |
parent | cdea52128f6099e8f84459823c45790a78264022 (diff) |
bnx2x: Reporting host statistics to management FW
This is required for NCSI statistics
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 228 |
1 files changed, 175 insertions, 53 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 7853977b8de2..88f30d254095 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -3365,53 +3365,6 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) | |||
3365 | } | 3365 | } |
3366 | } | 3366 | } |
3367 | 3367 | ||
3368 | static void bnx2x_stats_init(struct bnx2x *bp) | ||
3369 | { | ||
3370 | int port = BP_PORT(bp); | ||
3371 | int i; | ||
3372 | |||
3373 | bp->stats_pending = 0; | ||
3374 | bp->executer_idx = 0; | ||
3375 | bp->stats_counter = 0; | ||
3376 | |||
3377 | /* port stats */ | ||
3378 | if (!BP_NOMCP(bp)) | ||
3379 | bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx); | ||
3380 | else | ||
3381 | bp->port.port_stx = 0; | ||
3382 | DP(BNX2X_MSG_STATS, "port_stx 0x%x\n", bp->port.port_stx); | ||
3383 | |||
3384 | memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats)); | ||
3385 | bp->port.old_nig_stats.brb_discard = | ||
3386 | REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38); | ||
3387 | bp->port.old_nig_stats.brb_truncate = | ||
3388 | REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38); | ||
3389 | REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50, | ||
3390 | &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2); | ||
3391 | REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50, | ||
3392 | &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2); | ||
3393 | |||
3394 | /* function stats */ | ||
3395 | for_each_queue(bp, i) { | ||
3396 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
3397 | |||
3398 | memset(&fp->old_tclient, 0, | ||
3399 | sizeof(struct tstorm_per_client_stats)); | ||
3400 | memset(&fp->old_uclient, 0, | ||
3401 | sizeof(struct ustorm_per_client_stats)); | ||
3402 | memset(&fp->old_xclient, 0, | ||
3403 | sizeof(struct xstorm_per_client_stats)); | ||
3404 | memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); | ||
3405 | } | ||
3406 | |||
3407 | memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); | ||
3408 | memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats)); | ||
3409 | |||
3410 | bp->stats_state = STATS_STATE_DISABLED; | ||
3411 | if (IS_E1HMF(bp) && bp->port.pmf && bp->port.port_stx) | ||
3412 | bnx2x_stats_handle(bp, STATS_EVENT_PMF); | ||
3413 | } | ||
3414 | |||
3415 | static void bnx2x_hw_stats_post(struct bnx2x *bp) | 3368 | static void bnx2x_hw_stats_post(struct bnx2x *bp) |
3416 | { | 3369 | { |
3417 | struct dmae_command *dmae = &bp->stats_dmae; | 3370 | struct dmae_command *dmae = &bp->stats_dmae; |
@@ -3972,7 +3925,8 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) | |||
3972 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | 3925 | struct bnx2x_eth_stats *estats = &bp->eth_stats; |
3973 | int i; | 3926 | int i; |
3974 | 3927 | ||
3975 | memset(&(fstats->total_bytes_received_hi), 0, | 3928 | memcpy(&(fstats->total_bytes_received_hi), |
3929 | &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), | ||
3976 | sizeof(struct host_func_stats) - 2*sizeof(u32)); | 3930 | sizeof(struct host_func_stats) - 2*sizeof(u32)); |
3977 | estats->error_bytes_received_hi = 0; | 3931 | estats->error_bytes_received_hi = 0; |
3978 | estats->error_bytes_received_lo = 0; | 3932 | estats->error_bytes_received_lo = 0; |
@@ -4451,6 +4405,173 @@ static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) | |||
4451 | state, event, bp->stats_state); | 4405 | state, event, bp->stats_state); |
4452 | } | 4406 | } |
4453 | 4407 | ||
4408 | static void bnx2x_port_stats_base_init(struct bnx2x *bp) | ||
4409 | { | ||
4410 | struct dmae_command *dmae; | ||
4411 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
4412 | |||
4413 | /* sanity */ | ||
4414 | if (!bp->port.pmf || !bp->port.port_stx) { | ||
4415 | BNX2X_ERR("BUG!\n"); | ||
4416 | return; | ||
4417 | } | ||
4418 | |||
4419 | bp->executer_idx = 0; | ||
4420 | |||
4421 | dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); | ||
4422 | dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | | ||
4423 | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | | ||
4424 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
4425 | #ifdef __BIG_ENDIAN | ||
4426 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
4427 | #else | ||
4428 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
4429 | #endif | ||
4430 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
4431 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
4432 | dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); | ||
4433 | dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); | ||
4434 | dmae->dst_addr_lo = bp->port.port_stx >> 2; | ||
4435 | dmae->dst_addr_hi = 0; | ||
4436 | dmae->len = sizeof(struct host_port_stats) >> 2; | ||
4437 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
4438 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
4439 | dmae->comp_val = DMAE_COMP_VAL; | ||
4440 | |||
4441 | *stats_comp = 0; | ||
4442 | bnx2x_hw_stats_post(bp); | ||
4443 | bnx2x_stats_comp(bp); | ||
4444 | } | ||
4445 | |||
4446 | static void bnx2x_func_stats_base_init(struct bnx2x *bp) | ||
4447 | { | ||
4448 | int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX; | ||
4449 | int port = BP_PORT(bp); | ||
4450 | int func; | ||
4451 | u32 func_stx; | ||
4452 | |||
4453 | /* sanity */ | ||
4454 | if (!bp->port.pmf || !bp->func_stx) { | ||
4455 | BNX2X_ERR("BUG!\n"); | ||
4456 | return; | ||
4457 | } | ||
4458 | |||
4459 | /* save our func_stx */ | ||
4460 | func_stx = bp->func_stx; | ||
4461 | |||
4462 | for (vn = VN_0; vn < vn_max; vn++) { | ||
4463 | func = 2*vn + port; | ||
4464 | |||
4465 | bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); | ||
4466 | bnx2x_func_stats_init(bp); | ||
4467 | bnx2x_hw_stats_post(bp); | ||
4468 | bnx2x_stats_comp(bp); | ||
4469 | } | ||
4470 | |||
4471 | /* restore our func_stx */ | ||
4472 | bp->func_stx = func_stx; | ||
4473 | } | ||
4474 | |||
4475 | static void bnx2x_func_stats_base_update(struct bnx2x *bp) | ||
4476 | { | ||
4477 | struct dmae_command *dmae = &bp->stats_dmae; | ||
4478 | u32 *stats_comp = bnx2x_sp(bp, stats_comp); | ||
4479 | |||
4480 | /* sanity */ | ||
4481 | if (!bp->func_stx) { | ||
4482 | BNX2X_ERR("BUG!\n"); | ||
4483 | return; | ||
4484 | } | ||
4485 | |||
4486 | bp->executer_idx = 0; | ||
4487 | memset(dmae, 0, sizeof(struct dmae_command)); | ||
4488 | |||
4489 | dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | | ||
4490 | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | | ||
4491 | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | | ||
4492 | #ifdef __BIG_ENDIAN | ||
4493 | DMAE_CMD_ENDIANITY_B_DW_SWAP | | ||
4494 | #else | ||
4495 | DMAE_CMD_ENDIANITY_DW_SWAP | | ||
4496 | #endif | ||
4497 | (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | | ||
4498 | (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); | ||
4499 | dmae->src_addr_lo = bp->func_stx >> 2; | ||
4500 | dmae->src_addr_hi = 0; | ||
4501 | dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base)); | ||
4502 | dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats_base)); | ||
4503 | dmae->len = sizeof(struct host_func_stats) >> 2; | ||
4504 | dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); | ||
4505 | dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); | ||
4506 | dmae->comp_val = DMAE_COMP_VAL; | ||
4507 | |||
4508 | *stats_comp = 0; | ||
4509 | bnx2x_hw_stats_post(bp); | ||
4510 | bnx2x_stats_comp(bp); | ||
4511 | } | ||
4512 | |||
4513 | static void bnx2x_stats_init(struct bnx2x *bp) | ||
4514 | { | ||
4515 | int port = BP_PORT(bp); | ||
4516 | int func = BP_FUNC(bp); | ||
4517 | int i; | ||
4518 | |||
4519 | bp->stats_pending = 0; | ||
4520 | bp->executer_idx = 0; | ||
4521 | bp->stats_counter = 0; | ||
4522 | |||
4523 | /* port and func stats for management */ | ||
4524 | if (!BP_NOMCP(bp)) { | ||
4525 | bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx); | ||
4526 | bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); | ||
4527 | |||
4528 | } else { | ||
4529 | bp->port.port_stx = 0; | ||
4530 | bp->func_stx = 0; | ||
4531 | } | ||
4532 | DP(BNX2X_MSG_STATS, "port_stx 0x%x func_stx 0x%x\n", | ||
4533 | bp->port.port_stx, bp->func_stx); | ||
4534 | |||
4535 | /* port stats */ | ||
4536 | memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats)); | ||
4537 | bp->port.old_nig_stats.brb_discard = | ||
4538 | REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38); | ||
4539 | bp->port.old_nig_stats.brb_truncate = | ||
4540 | REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38); | ||
4541 | REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50, | ||
4542 | &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2); | ||
4543 | REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50, | ||
4544 | &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2); | ||
4545 | |||
4546 | /* function stats */ | ||
4547 | for_each_queue(bp, i) { | ||
4548 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
4549 | |||
4550 | memset(&fp->old_tclient, 0, | ||
4551 | sizeof(struct tstorm_per_client_stats)); | ||
4552 | memset(&fp->old_uclient, 0, | ||
4553 | sizeof(struct ustorm_per_client_stats)); | ||
4554 | memset(&fp->old_xclient, 0, | ||
4555 | sizeof(struct xstorm_per_client_stats)); | ||
4556 | memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); | ||
4557 | } | ||
4558 | |||
4559 | memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); | ||
4560 | memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats)); | ||
4561 | |||
4562 | bp->stats_state = STATS_STATE_DISABLED; | ||
4563 | |||
4564 | if (bp->port.pmf) { | ||
4565 | if (bp->port.port_stx) | ||
4566 | bnx2x_port_stats_base_init(bp); | ||
4567 | |||
4568 | if (bp->func_stx) | ||
4569 | bnx2x_func_stats_base_init(bp); | ||
4570 | |||
4571 | } else if (bp->func_stx) | ||
4572 | bnx2x_func_stats_base_update(bp); | ||
4573 | } | ||
4574 | |||
4454 | static void bnx2x_timer(unsigned long data) | 4575 | static void bnx2x_timer(unsigned long data) |
4455 | { | 4576 | { |
4456 | struct bnx2x *bp = (struct bnx2x *) data; | 4577 | struct bnx2x *bp = (struct bnx2x *) data; |
@@ -4933,6 +5054,10 @@ static void bnx2x_init_tx_ring(struct bnx2x *bp) | |||
4933 | fp->tx_cons_sb = BNX2X_TX_SB_INDEX; | 5054 | fp->tx_cons_sb = BNX2X_TX_SB_INDEX; |
4934 | fp->tx_pkt = 0; | 5055 | fp->tx_pkt = 0; |
4935 | } | 5056 | } |
5057 | |||
5058 | /* clean tx statistics */ | ||
5059 | for_each_rx_queue(bp, i) | ||
5060 | bnx2x_fp(bp, i, tx_pkt) = 0; | ||
4936 | } | 5061 | } |
4937 | 5062 | ||
4938 | static void bnx2x_init_sp_ring(struct bnx2x *bp) | 5063 | static void bnx2x_init_sp_ring(struct bnx2x *bp) |
@@ -6412,11 +6537,8 @@ static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) | |||
6412 | bp->fw_drv_pulse_wr_seq = | 6537 | bp->fw_drv_pulse_wr_seq = |
6413 | (SHMEM_RD(bp, func_mb[func].drv_pulse_mb) & | 6538 | (SHMEM_RD(bp, func_mb[func].drv_pulse_mb) & |
6414 | DRV_PULSE_SEQ_MASK); | 6539 | DRV_PULSE_SEQ_MASK); |
6415 | bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); | 6540 | DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); |
6416 | DP(BNX2X_MSG_MCP, "drv_pulse 0x%x func_stx 0x%x\n", | 6541 | } |
6417 | bp->fw_drv_pulse_wr_seq, bp->func_stx); | ||
6418 | } else | ||
6419 | bp->func_stx = 0; | ||
6420 | 6542 | ||
6421 | /* this needs to be done before gunzip end */ | 6543 | /* this needs to be done before gunzip end */ |
6422 | bnx2x_zero_def_sb(bp); | 6544 | bnx2x_zero_def_sb(bp); |