aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2009-08-12 04:23:17 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-13 02:02:38 -0400
commit6fe49bb978de3de0ba7ff9d6b2d55a15518db2a3 (patch)
treead6e21f76c6d166697dbd7e6605ffc12b91b419f
parentcdea52128f6099e8f84459823c45790a78264022 (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>
-rw-r--r--drivers/net/bnx2x.h1
-rw-r--r--drivers/net/bnx2x_main.c228
2 files changed, 176 insertions, 53 deletions
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 903c89d8518a..1d0b72716f7a 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -777,6 +777,7 @@ struct bnx2x_slowpath {
777 struct nig_stats nig_stats; 777 struct nig_stats nig_stats;
778 struct host_port_stats port_stats; 778 struct host_port_stats port_stats;
779 struct host_func_stats func_stats; 779 struct host_func_stats func_stats;
780 struct host_func_stats func_stats_base;
780 781
781 u32 wb_comp; 782 u32 wb_comp;
782 u32 wb_data[4]; 783 u32 wb_data[4];
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
3368static 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
3415static void bnx2x_hw_stats_post(struct bnx2x *bp) 3368static 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
4408static 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
4446static 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
4475static 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
4513static 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
4454static void bnx2x_timer(unsigned long data) 4575static 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
4938static void bnx2x_init_sp_ring(struct bnx2x *bp) 5063static 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);