Commit bb2a0f7a authored by Yitchak Gertner's avatar Yitchak Gertner Committed by David S. Miller

bnx2x: New statistics code

To avoid race conditions with link up/down and driver up/down - the
statistics handling was re-written in a form of state machine.
Also supporting statistics for 57711
Signed-off-by: default avatarYitchak Gertner <gertner@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 34f80b04
...@@ -132,243 +132,6 @@ ...@@ -132,243 +132,6 @@
#define is_multi(bp) (bp->num_queues > 1) #define is_multi(bp) (bp->num_queues > 1)
struct regp {
u32 lo;
u32 hi;
};
struct bmac_stats {
struct regp tx_gtpkt;
struct regp tx_gtxpf;
struct regp tx_gtfcs;
struct regp tx_gtmca;
struct regp tx_gtgca;
struct regp tx_gtfrg;
struct regp tx_gtovr;
struct regp tx_gt64;
struct regp tx_gt127;
struct regp tx_gt255; /* 10 */
struct regp tx_gt511;
struct regp tx_gt1023;
struct regp tx_gt1518;
struct regp tx_gt2047;
struct regp tx_gt4095;
struct regp tx_gt9216;
struct regp tx_gt16383;
struct regp tx_gtmax;
struct regp tx_gtufl;
struct regp tx_gterr; /* 20 */
struct regp tx_gtbyt;
struct regp rx_gr64;
struct regp rx_gr127;
struct regp rx_gr255;
struct regp rx_gr511;
struct regp rx_gr1023;
struct regp rx_gr1518;
struct regp rx_gr2047;
struct regp rx_gr4095;
struct regp rx_gr9216; /* 30 */
struct regp rx_gr16383;
struct regp rx_grmax;
struct regp rx_grpkt;
struct regp rx_grfcs;
struct regp rx_grmca;
struct regp rx_grbca;
struct regp rx_grxcf;
struct regp rx_grxpf;
struct regp rx_grxuo;
struct regp rx_grjbr; /* 40 */
struct regp rx_grovr;
struct regp rx_grflr;
struct regp rx_grmeg;
struct regp rx_grmeb;
struct regp rx_grbyt;
struct regp rx_grund;
struct regp rx_grfrg;
struct regp rx_grerb;
struct regp rx_grfre;
struct regp rx_gripj; /* 50 */
};
struct emac_stats {
u32 rx_ifhcinoctets ;
u32 rx_ifhcinbadoctets ;
u32 rx_etherstatsfragments ;
u32 rx_ifhcinucastpkts ;
u32 rx_ifhcinmulticastpkts ;
u32 rx_ifhcinbroadcastpkts ;
u32 rx_dot3statsfcserrors ;
u32 rx_dot3statsalignmenterrors ;
u32 rx_dot3statscarriersenseerrors ;
u32 rx_xonpauseframesreceived ; /* 10 */
u32 rx_xoffpauseframesreceived ;
u32 rx_maccontrolframesreceived ;
u32 rx_xoffstateentered ;
u32 rx_dot3statsframestoolong ;
u32 rx_etherstatsjabbers ;
u32 rx_etherstatsundersizepkts ;
u32 rx_etherstatspkts64octets ;
u32 rx_etherstatspkts65octetsto127octets ;
u32 rx_etherstatspkts128octetsto255octets ;
u32 rx_etherstatspkts256octetsto511octets ; /* 20 */
u32 rx_etherstatspkts512octetsto1023octets ;
u32 rx_etherstatspkts1024octetsto1522octets;
u32 rx_etherstatspktsover1522octets ;
u32 rx_falsecarriererrors ;
u32 tx_ifhcoutoctets ;
u32 tx_ifhcoutbadoctets ;
u32 tx_etherstatscollisions ;
u32 tx_outxonsent ;
u32 tx_outxoffsent ;
u32 tx_flowcontroldone ; /* 30 */
u32 tx_dot3statssinglecollisionframes ;
u32 tx_dot3statsmultiplecollisionframes ;
u32 tx_dot3statsdeferredtransmissions ;
u32 tx_dot3statsexcessivecollisions ;
u32 tx_dot3statslatecollisions ;
u32 tx_ifhcoutucastpkts ;
u32 tx_ifhcoutmulticastpkts ;
u32 tx_ifhcoutbroadcastpkts ;
u32 tx_etherstatspkts64octets ;
u32 tx_etherstatspkts65octetsto127octets ; /* 40 */
u32 tx_etherstatspkts128octetsto255octets ;
u32 tx_etherstatspkts256octetsto511octets ;
u32 tx_etherstatspkts512octetsto1023octets ;
u32 tx_etherstatspkts1024octetsto1522octet ;
u32 tx_etherstatspktsover1522octets ;
u32 tx_dot3statsinternalmactransmiterrors ; /* 46 */
};
union mac_stats {
struct emac_stats emac;
struct bmac_stats bmac;
};
struct nig_stats {
u32 brb_discard;
u32 brb_packet;
u32 brb_truncate;
u32 flow_ctrl_discard;
u32 flow_ctrl_octets;
u32 flow_ctrl_packet;
u32 mng_discard;
u32 mng_octet_inp;
u32 mng_octet_out;
u32 mng_packet_inp;
u32 mng_packet_out;
u32 pbf_octets;
u32 pbf_packet;
u32 safc_inp;
u32 done;
u32 pad;
};
struct bnx2x_eth_stats {
u32 pad; /* to make long counters u64 aligned */
u32 mac_stx_start;
u32 total_bytes_received_hi;
u32 total_bytes_received_lo;
u32 total_bytes_transmitted_hi;
u32 total_bytes_transmitted_lo;
u32 total_unicast_packets_received_hi;
u32 total_unicast_packets_received_lo;
u32 total_multicast_packets_received_hi;
u32 total_multicast_packets_received_lo;
u32 total_broadcast_packets_received_hi;
u32 total_broadcast_packets_received_lo;
u32 total_unicast_packets_transmitted_hi;
u32 total_unicast_packets_transmitted_lo;
u32 total_multicast_packets_transmitted_hi;
u32 total_multicast_packets_transmitted_lo;
u32 total_broadcast_packets_transmitted_hi;
u32 total_broadcast_packets_transmitted_lo;
u32 crc_receive_errors;
u32 alignment_errors;
u32 false_carrier_detections;
u32 runt_packets_received;
u32 jabber_packets_received;
u32 pause_xon_frames_received;
u32 pause_xoff_frames_received;
u32 pause_xon_frames_transmitted;
u32 pause_xoff_frames_transmitted;
u32 single_collision_transmit_frames;
u32 multiple_collision_transmit_frames;
u32 late_collision_frames;
u32 excessive_collision_frames;
u32 control_frames_received;
u32 frames_received_64_bytes;
u32 frames_received_65_127_bytes;
u32 frames_received_128_255_bytes;
u32 frames_received_256_511_bytes;
u32 frames_received_512_1023_bytes;
u32 frames_received_1024_1522_bytes;
u32 frames_received_1523_9022_bytes;
u32 frames_transmitted_64_bytes;
u32 frames_transmitted_65_127_bytes;
u32 frames_transmitted_128_255_bytes;
u32 frames_transmitted_256_511_bytes;
u32 frames_transmitted_512_1023_bytes;
u32 frames_transmitted_1024_1522_bytes;
u32 frames_transmitted_1523_9022_bytes;
u32 valid_bytes_received_hi;
u32 valid_bytes_received_lo;
u32 error_runt_packets_received;
u32 error_jabber_packets_received;
u32 mac_stx_end;
u32 pad2;
u32 stat_IfHCInBadOctets_hi;
u32 stat_IfHCInBadOctets_lo;
u32 stat_IfHCOutBadOctets_hi;
u32 stat_IfHCOutBadOctets_lo;
u32 stat_Dot3statsFramesTooLong;
u32 stat_Dot3statsInternalMacTransmitErrors;
u32 stat_Dot3StatsCarrierSenseErrors;
u32 stat_Dot3StatsDeferredTransmissions;
u32 stat_FlowControlDone;
u32 stat_XoffStateEntered;
u32 x_total_sent_bytes_hi;
u32 x_total_sent_bytes_lo;
u32 x_total_sent_pkts;
u32 t_rcv_unicast_bytes_hi;
u32 t_rcv_unicast_bytes_lo;
u32 t_rcv_broadcast_bytes_hi;
u32 t_rcv_broadcast_bytes_lo;
u32 t_rcv_multicast_bytes_hi;
u32 t_rcv_multicast_bytes_lo;
u32 t_total_rcv_pkt;
u32 checksum_discard;
u32 packets_too_big_discard;
u32 no_buff_discard;
u32 ttl0_discard;
u32 mac_discard;
u32 mac_filter_discard;
u32 xxoverflow_discard;
u32 brb_truncate_discard;
u32 brb_discard;
u32 brb_packet;
u32 brb_truncate;
u32 flow_ctrl_discard;
u32 flow_ctrl_octets;
u32 flow_ctrl_packet;
u32 mng_discard;
u32 mng_octet_inp;
u32 mng_octet_out;
u32 mng_packet_inp;
u32 mng_packet_out;
u32 pbf_octets;
u32 pbf_packet;
u32 safc_inp;
u32 driver_xoff;
u32 number_of_bugs_found_in_stats_spec; /* just kidding */
};
#define bnx2x_sp_check(bp, var) ((bp->slowpath) ? (&bp->slowpath->var) : NULL) #define bnx2x_sp_check(bp, var) ((bp->slowpath) ? (&bp->slowpath->var) : NULL)
struct sw_rx_bd { struct sw_rx_bd {
...@@ -447,6 +210,10 @@ struct bnx2x_fastpath { ...@@ -447,6 +210,10 @@ struct bnx2x_fastpath {
/* This is needed for determening of last_max */ /* This is needed for determening of last_max */
#define SUB_S16(a, b) (s16)((s16)(a) - (s16)(b)) #define SUB_S16(a, b) (s16)((s16)(a) - (s16)(b))
#define BD_UNMAP_ADDR(bd) HILO_U64(le32_to_cpu((bd)->addr_hi), \
le32_to_cpu((bd)->addr_lo))
#define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes))
/* stuff added to make the code fit 80Col */ /* stuff added to make the code fit 80Col */
#define CQE_TYPE(cqe_fp_flags) ((cqe_fp_flags) & ETH_FAST_PATH_RX_CQE_TYPE) #define CQE_TYPE(cqe_fp_flags) ((cqe_fp_flags) & ETH_FAST_PATH_RX_CQE_TYPE)
...@@ -456,6 +223,9 @@ struct bnx2x_fastpath { ...@@ -456,6 +223,9 @@ struct bnx2x_fastpath {
ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG) ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)
#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES)
#define FP_CSB_FUNC_OFF (2 + 2*HC_CSTORM_SB_NUM_INDICES)
#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS #define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS
#define U_SB_ETH_RX_BD_INDEX HC_INDEX_U_ETH_RX_BD_CONS #define U_SB_ETH_RX_BD_INDEX HC_INDEX_U_ETH_RX_BD_CONS
#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS #define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS
...@@ -533,6 +303,27 @@ struct bnx2x_common { ...@@ -533,6 +303,27 @@ struct bnx2x_common {
/* port */ /* port */
struct nig_stats {
u32 brb_discard;
u32 brb_packet;
u32 brb_truncate;
u32 flow_ctrl_discard;
u32 flow_ctrl_octets;
u32 flow_ctrl_packet;
u32 mng_discard;
u32 mng_octet_inp;
u32 mng_octet_out;
u32 mng_packet_inp;
u32 mng_packet_out;
u32 pbf_octets;
u32 pbf_packet;
u32 safc_inp;
u32 egress_mac_pkt0_lo;
u32 egress_mac_pkt0_hi;
u32 egress_mac_pkt1_lo;
u32 egress_mac_pkt1_hi;
};
struct bnx2x_port { struct bnx2x_port {
u32 pmf; u32 pmf;
...@@ -558,7 +349,144 @@ struct bnx2x_port { ...@@ -558,7 +349,144 @@ struct bnx2x_port {
/* end of port */ /* end of port */
#define MAC_STX_NA 0xffffffff
enum bnx2x_stats_event {
STATS_EVENT_PMF = 0,
STATS_EVENT_LINK_UP,
STATS_EVENT_UPDATE,
STATS_EVENT_STOP,
STATS_EVENT_MAX
};
enum bnx2x_stats_state {
STATS_STATE_DISABLED = 0,
STATS_STATE_ENABLED,
STATS_STATE_MAX
};
struct bnx2x_eth_stats {
u32 total_bytes_received_hi;
u32 total_bytes_received_lo;
u32 total_bytes_transmitted_hi;
u32 total_bytes_transmitted_lo;
u32 total_unicast_packets_received_hi;
u32 total_unicast_packets_received_lo;
u32 total_multicast_packets_received_hi;
u32 total_multicast_packets_received_lo;
u32 total_broadcast_packets_received_hi;
u32 total_broadcast_packets_received_lo;
u32 total_unicast_packets_transmitted_hi;
u32 total_unicast_packets_transmitted_lo;
u32 total_multicast_packets_transmitted_hi;
u32 total_multicast_packets_transmitted_lo;
u32 total_broadcast_packets_transmitted_hi;
u32 total_broadcast_packets_transmitted_lo;
u32 valid_bytes_received_hi;
u32 valid_bytes_received_lo;
u32 error_bytes_received_hi;
u32 error_bytes_received_lo;
u32 rx_stat_ifhcinbadoctets_hi;
u32 rx_stat_ifhcinbadoctets_lo;
u32 tx_stat_ifhcoutbadoctets_hi;
u32 tx_stat_ifhcoutbadoctets_lo;
u32 rx_stat_dot3statsfcserrors_hi;
u32 rx_stat_dot3statsfcserrors_lo;
u32 rx_stat_dot3statsalignmenterrors_hi;
u32 rx_stat_dot3statsalignmenterrors_lo;
u32 rx_stat_dot3statscarriersenseerrors_hi;
u32 rx_stat_dot3statscarriersenseerrors_lo;
u32 rx_stat_falsecarriererrors_hi;
u32 rx_stat_falsecarriererrors_lo;
u32 rx_stat_etherstatsundersizepkts_hi;
u32 rx_stat_etherstatsundersizepkts_lo;
u32 rx_stat_dot3statsframestoolong_hi;
u32 rx_stat_dot3statsframestoolong_lo;
u32 rx_stat_etherstatsfragments_hi;
u32 rx_stat_etherstatsfragments_lo;
u32 rx_stat_etherstatsjabbers_hi;
u32 rx_stat_etherstatsjabbers_lo;
u32 rx_stat_maccontrolframesreceived_hi;
u32 rx_stat_maccontrolframesreceived_lo;
u32 rx_stat_bmac_xpf_hi;
u32 rx_stat_bmac_xpf_lo;
u32 rx_stat_bmac_xcf_hi;
u32 rx_stat_bmac_xcf_lo;
u32 rx_stat_xoffstateentered_hi;
u32 rx_stat_xoffstateentered_lo;
u32 rx_stat_xonpauseframesreceived_hi;
u32 rx_stat_xonpauseframesreceived_lo;
u32 rx_stat_xoffpauseframesreceived_hi;
u32 rx_stat_xoffpauseframesreceived_lo;
u32 tx_stat_outxonsent_hi;
u32 tx_stat_outxonsent_lo;
u32 tx_stat_outxoffsent_hi;
u32 tx_stat_outxoffsent_lo;
u32 tx_stat_flowcontroldone_hi;
u32 tx_stat_flowcontroldone_lo;
u32 tx_stat_etherstatscollisions_hi;
u32 tx_stat_etherstatscollisions_lo;
u32 tx_stat_dot3statssinglecollisionframes_hi;
u32 tx_stat_dot3statssinglecollisionframes_lo;
u32 tx_stat_dot3statsmultiplecollisionframes_hi;
u32 tx_stat_dot3statsmultiplecollisionframes_lo;
u32 tx_stat_dot3statsdeferredtransmissions_hi;
u32 tx_stat_dot3statsdeferredtransmissions_lo;
u32 tx_stat_dot3statsexcessivecollisions_hi;
u32 tx_stat_dot3statsexcessivecollisions_lo;
u32 tx_stat_dot3statslatecollisions_hi;
u32 tx_stat_dot3statslatecollisions_lo;
u32 tx_stat_etherstatspkts64octets_hi;
u32 tx_stat_etherstatspkts64octets_lo;
u32 tx_stat_etherstatspkts65octetsto127octets_hi;
u32 tx_stat_etherstatspkts65octetsto127octets_lo;
u32 tx_stat_etherstatspkts128octetsto255octets_hi;
u32 tx_stat_etherstatspkts128octetsto255octets_lo;
u32 tx_stat_etherstatspkts256octetsto511octets_hi;
u32 tx_stat_etherstatspkts256octetsto511octets_lo;
u32 tx_stat_etherstatspkts512octetsto1023octets_hi;
u32 tx_stat_etherstatspkts512octetsto1023octets_lo;
u32 tx_stat_etherstatspkts1024octetsto1522octets_hi;
u32 tx_stat_etherstatspkts1024octetsto1522octets_lo;
u32 tx_stat_etherstatspktsover1522octets_hi;
u32 tx_stat_etherstatspktsover1522octets_lo;
u32 tx_stat_bmac_2047_hi;
u32 tx_stat_bmac_2047_lo;
u32 tx_stat_bmac_4095_hi;
u32 tx_stat_bmac_4095_lo;
u32 tx_stat_bmac_9216_hi;
u32 tx_stat_bmac_9216_lo;
u32 tx_stat_bmac_16383_hi;
u32 tx_stat_bmac_16383_lo;
u32 tx_stat_dot3statsinternalmactransmiterrors_hi;
u32 tx_stat_dot3statsinternalmactransmiterrors_lo;
u32 tx_stat_bmac_ufl_hi;
u32 tx_stat_bmac_ufl_lo;
u32 brb_drop_hi;
u32 brb_drop_lo;
u32 jabber_packets_received;
u32 etherstatspkts1024octetsto1522octets_hi;
u32 etherstatspkts1024octetsto1522octets_lo;
u32 etherstatspktsover1522octets_hi;
u32 etherstatspktsover1522octets_lo;
u32 no_buff_discard;
u32 mac_filter_discard;
u32 xxoverflow_discard;
u32 brb_truncate_discard;
u32 mac_discard;
u32 driver_xoff;
};
#define STATS_OFFSET32(stat_name) \
(offsetof(struct bnx2x_eth_stats, stat_name) / 4)
#ifdef BNX2X_MULTI #ifdef BNX2X_MULTI
#define MAX_CONTEXT 16 #define MAX_CONTEXT 16
...@@ -571,7 +499,7 @@ union cdu_context { ...@@ -571,7 +499,7 @@ union cdu_context {
char pad[1024]; char pad[1024];
}; };
#define MAX_DMAE_C 6 #define MAX_DMAE_C 8
/* DMA memory not used in fastpath */ /* DMA memory not used in fastpath */
struct bnx2x_slowpath { struct bnx2x_slowpath {
...@@ -583,12 +511,13 @@ struct bnx2x_slowpath { ...@@ -583,12 +511,13 @@ struct bnx2x_slowpath {
/* used by dmae command executer */ /* used by dmae command executer */
struct dmae_command dmae[MAX_DMAE_C]; struct dmae_command dmae[MAX_DMAE_C];
union mac_stats mac_stats; u32 stats_comp;
struct nig_stats nig; union mac_stats mac_stats;
struct bnx2x_eth_stats eth_stats; struct nig_stats nig_stats;
struct host_port_stats port_stats;
struct host_func_stats func_stats;
u32 wb_comp; u32 wb_comp;
#define BNX2X_WB_COMP_VAL 0xe0d0d0ae
u32 wb_data[4]; u32 wb_data[4];
}; };
...@@ -657,10 +586,10 @@ struct bnx2x { ...@@ -657,10 +586,10 @@ struct bnx2x {
/* used to synchronize spq accesses */ /* used to synchronize spq accesses */
spinlock_t spq_lock; spinlock_t spq_lock;
/* Flag for marking that there is either /* Flags for marking that there is a STAT_QUERY or
* STAT_QUERY or CFC DELETE ramrod pending SET_MAC ramrod pending */
*/ u8 stats_pending;
u8 stat_pending; u8 set_mac_pending;
/* End of fileds used in the performance code paths */ /* End of fileds used in the performance code paths */
...@@ -766,62 +695,31 @@ struct bnx2x { ...@@ -766,62 +695,31 @@ struct bnx2x {
dma_addr_t qm_mapping; dma_addr_t qm_mapping;
#endif #endif
char *name;
/* used to synchronize stats collecting */
int stats_state;
#define STATS_STATE_DISABLE 0
#define STATS_STATE_ENABLE 1
#define STATS_STATE_STOP 2 /* stop stats on next iteration */
/* used by dmae command loader */
struct dmae_command dmae;
int executer_idx;
int dmae_ready; int dmae_ready;
/* used to synchronize dmae accesses */ /* used to synchronize dmae accesses */
struct mutex dmae_mutex; struct mutex dmae_mutex;
struct dmae_command init_dmae; struct dmae_command init_dmae;
/* used to synchronize stats collecting */
int stats_state;
/* used by dmae command loader */
struct dmae_command stats_dmae;
int executer_idx;
u16 stats_counter;
u32 old_brb_discard;
struct bmac_stats old_bmac;
struct tstorm_per_client_stats old_tclient; struct tstorm_per_client_stats old_tclient;
struct z_stream_s *strm; struct xstorm_per_client_stats old_xclient;
void *gunzip_buf; struct bnx2x_eth_stats eth_stats;
dma_addr_t gunzip_mapping;
int gunzip_outlen; struct z_stream_s *strm;
void *gunzip_buf;
dma_addr_t gunzip_mapping;
int gunzip_outlen;
#define FW_BUF_SIZE 0x8000 #define FW_BUF_SIZE 0x8000
}; };
/* DMAE command defines */
#define DMAE_CMD_SRC_PCI 0
#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC
#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT)
#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT)
#define DMAE_CMD_C_DST_PCI 0
#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT)
#define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE
#define DMAE_CMD_ENDIANITY_NO_SWAP (0 << DMAE_COMMAND_ENDIANITY_SHIFT)
#define DMAE_CMD_ENDIANITY_B_SWAP (1 << DMAE_COMMAND_ENDIANITY_SHIFT)
#define DMAE_CMD_ENDIANITY_DW_SWAP (2 << DMAE_COMMAND_ENDIANITY_SHIFT)
#define DMAE_CMD_ENDIANITY_B_DW_SWAP (3 << DMAE_COMMAND_ENDIANITY_SHIFT)
#define DMAE_CMD_PORT_0 0
#define DMAE_CMD_PORT_1 DMAE_COMMAND_PORT
#define DMAE_CMD_SRC_RESET DMAE_COMMAND_SRC_RESET
#define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET
#define DMAE_LEN32_MAX 0x400
void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32); void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
u32 len32); u32 len32);
...@@ -875,11 +773,6 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode); ...@@ -875,11 +773,6 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode);
#define CQE_CMD(x) (le32_to_cpu(x) >> \ #define CQE_CMD(x) (le32_to_cpu(x) >> \
COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT) COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT)
#define BD_UNMAP_ADDR(bd) HILO_U64(le32_to_cpu((bd)->addr_hi), \
le32_to_cpu((bd)->addr_lo))
#define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes))
#define STROM_ASSERT_ARRAY_SIZE 50 #define STROM_ASSERT_ARRAY_SIZE 50
...@@ -895,10 +788,6 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode); ...@@ -895,10 +788,6 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode);
#define MAX_SPQ_PENDING 8 #define MAX_SPQ_PENDING 8
#define BNX2X_NUM_STATS 34
#define BNX2X_NUM_TESTS 1
#define DPM_TRIGER_TYPE 0x40 #define DPM_TRIGER_TYPE 0x40
#define DOORBELL(bp, cid, val) \ #define DOORBELL(bp, cid, val) \
do { \ do { \
...@@ -931,6 +820,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, ...@@ -931,6 +820,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define UNLOAD_NORMAL 0 #define UNLOAD_NORMAL 0
#define UNLOAD_CLOSE 1 #define UNLOAD_CLOSE 1
/* DMAE command defines */ /* DMAE command defines */
#define DMAE_CMD_SRC_PCI 0 #define DMAE_CMD_SRC_PCI 0
#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC #define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC
...@@ -973,7 +863,16 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, ...@@ -973,7 +863,16 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define PCICFG_LINK_SPEED 0xf0000 #define PCICFG_LINK_SPEED 0xf0000
#define PCICFG_LINK_SPEED_SHIFT 16 #define PCICFG_LINK_SPEED_SHIFT 16
#define BMAC_CONTROL_RX_ENABLE 2
#define BNX2X_NUM_STATS 39
#define BNX2X_NUM_TESTS 8
#define BNX2X_MAC_LOOPBACK 0
#define BNX2X_PHY_LOOPBACK 1
#define BNX2X_MAC_LOOPBACK_FAILED 1
#define BNX2X_PHY_LOOPBACK_FAILED 2
#define BNX2X_LOOPBACK_FAILED (BNX2X_MAC_LOOPBACK_FAILED | \
BNX2X_PHY_LOOPBACK_FAILED)
#define pbd_tcp_flags(skb) (ntohl(tcp_flag_word(tcp_hdr(skb)))>>16 & 0xff) #define pbd_tcp_flags(skb) (ntohl(tcp_flag_word(tcp_hdr(skb)))>>16 & 0xff)
......
...@@ -878,6 +878,337 @@ struct shmem_region { /* SharedMem Offset (size) */ ...@@ -878,6 +878,337 @@ struct shmem_region { /* SharedMem Offset (size) */
}; /* 0x6dc */ }; /* 0x6dc */
struct emac_stats {
u32 rx_stat_ifhcinoctets;
u32 rx_stat_ifhcinbadoctets;
u32 rx_stat_etherstatsfragments;
u32 rx_stat_ifhcinucastpkts;
u32 rx_stat_ifhcinmulticastpkts;
u32 rx_stat_ifhcinbroadcastpkts;
u32 rx_stat_dot3statsfcserrors;
u32 rx_stat_dot3statsalignmenterrors;
u32 rx_stat_dot3statscarriersenseerrors;
u32 rx_stat_xonpauseframesreceived;
u32 rx_stat_xoffpauseframesreceived;
u32 rx_stat_maccontrolframesreceived;
u32 rx_stat_xoffstateentered;
u32 rx_stat_dot3statsframestoolong;
u32 rx_stat_etherstatsjabbers;
u32 rx_stat_etherstatsundersizepkts;
u32 rx_stat_etherstatspkts64octets;
u32 rx_stat_etherstatspkts65octetsto127octets;
u32 rx_stat_etherstatspkts128octetsto255octets;
u32 rx_stat_etherstatspkts256octetsto511octets;
u32 rx_stat_etherstatspkts512octetsto1023octets;
u32 rx_stat_etherstatspkts1024octetsto1522octets;
u32 rx_stat_etherstatspktsover1522octets;
u32 rx_stat_falsecarriererrors;
u32 tx_stat_ifhcoutoctets;
u32 tx_stat_ifhcoutbadoctets;
u32 tx_stat_etherstatscollisions;
u32 tx_stat_outxonsent;
u32 tx_stat_outxoffsent;
u32 tx_stat_flowcontroldone;
u32 tx_stat_dot3statssinglecollisionframes;
u32 tx_stat_dot3statsmultiplecollisionframes;
u32 tx_stat_dot3statsdeferredtransmissions;
u32 tx_stat_dot3statsexcessivecollisions;
u32 tx_stat_dot3statslatecollisions;
u32 tx_stat_ifhcoutucastpkts;
u32 tx_stat_ifhcoutmulticastpkts;
u32 tx_stat_ifhcoutbroadcastpkts;
u32 tx_stat_etherstatspkts64octets;
u32 tx_stat_etherstatspkts65octetsto127octets;
u32 tx_stat_etherstatspkts128octetsto255octets;
u32 tx_stat_etherstatspkts256octetsto511octets;
u32 tx_stat_etherstatspkts512octetsto1023octets;
u32 tx_stat_etherstatspkts1024octetsto1522octets;
u32 tx_stat_etherstatspktsover1522octets;
u32 tx_stat_dot3statsinternalmactransmiterrors;
};
struct bmac_stats {
u32 tx_stat_gtpkt_lo;
u32 tx_stat_gtpkt_hi;
u32 tx_stat_gtxpf_lo;
u32 tx_stat_gtxpf_hi;
u32 tx_stat_gtfcs_lo;
u32 tx_stat_gtfcs_hi;
u32 tx_stat_gtmca_lo;
u32 tx_stat_gtmca_hi;
u32 tx_stat_gtbca_lo;
u32 tx_stat_gtbca_hi;
u32 tx_stat_gtfrg_lo;
u32 tx_stat_gtfrg_hi;
u32 tx_stat_gtovr_lo;
u32 tx_stat_gtovr_hi;
u32 tx_stat_gt64_lo;
u32 tx_stat_gt64_hi;
u32 tx_stat_gt127_lo;
u32 tx_stat_gt127_hi;
u32 tx_stat_gt255_lo;
u32 tx_stat_gt255_hi;
u32 tx_stat_gt511_lo;
u32 tx_stat_gt511_hi;
u32 tx_stat_gt1023_lo;
u32 tx_stat_gt1023_hi;
u32 tx_stat_gt1518_lo;
u32 tx_stat_gt1518_hi;
u32 tx_stat_gt2047_lo;
u32 tx_stat_gt2047_hi;
u32 tx_stat_gt4095_lo;
u32 tx_stat_gt4095_hi;
u32 tx_stat_gt9216_lo;
u32 tx_stat_gt9216_hi;
u32 tx_stat_gt16383_lo;
u32 tx_stat_gt16383_hi;
u32 tx_stat_gtmax_lo;
u32 tx_stat_gtmax_hi;
u32 tx_stat_gtufl_lo;
u32 tx_stat_gtufl_hi;
u32 tx_stat_gterr_lo;
u32 tx_stat_gterr_hi;
u32 tx_stat_gtbyt_lo;
u32 tx_stat_gtbyt_hi;
u32 rx_stat_gr64_lo;
u32 rx_stat_gr64_hi;
u32 rx_stat_gr127_lo;
u32 rx_stat_gr127_hi;
u32 rx_stat_gr255_lo;
u32 rx_stat_gr255_hi;
u32 rx_stat_gr511_lo;
u32 rx_stat_gr511_hi;
u32 rx_stat_gr1023_lo;
u32 rx_stat_gr1023_hi;
u32 rx_stat_gr1518_lo;
u32 rx_stat_gr1518_hi;
u32 rx_stat_gr2047_lo;
u32 rx_stat_gr2047_hi;
u32 rx_stat_gr4095_lo;
u32 rx_stat_gr4095_hi;
u32 rx_stat_gr9216_lo;
u32 rx_stat_gr9216_hi;
u32 rx_stat_gr16383_lo;
u32 rx_stat_gr16383_hi;
u32 rx_stat_grmax_lo;
u32 rx_stat_grmax_hi;
u32 rx_stat_grpkt_lo;
u32 rx_stat_grpkt_hi;
u32 rx_stat_grfcs_lo;
u32 rx_stat_grfcs_hi;
u32 rx_stat_grmca_lo;
u32 rx_stat_grmca_hi;
u32 rx_stat_grbca_lo;
u32 rx_stat_grbca_hi;
u32 rx_stat_grxcf_lo;
u32 rx_stat_grxcf_hi;
u32 rx_stat_grxpf_lo;
u32 rx_stat_grxpf_hi;
u32 rx_stat_grxuo_lo;
u32 rx_stat_grxuo_hi;
u32 rx_stat_grjbr_lo;
u32 rx_stat_grjbr_hi;
u32 rx_stat_grovr_lo;
u32 rx_stat_grovr_hi;
u32 rx_stat_grflr_lo;
u32 rx_stat_grflr_hi;
u32 rx_stat_grmeg_lo;
u32 rx_stat_grmeg_hi;
u32 rx_stat_grmeb_lo;
u32 rx_stat_grmeb_hi;
u32 rx_stat_grbyt_lo;
u32 rx_stat_grbyt_hi;
u32 rx_stat_grund_lo;
u32 rx_stat_grund_hi;
u32 rx_stat_grfrg_lo;
u32 rx_stat_grfrg_hi;
u32 rx_stat_grerb_lo;
u32 rx_stat_grerb_hi;
u32 rx_stat_grfre_lo;
u32 rx_stat_grfre_hi;
u32 rx_stat_gripj_lo;
u32 rx_stat_gripj_hi;
};
union mac_stats {
struct emac_stats emac_stats;
struct bmac_stats bmac_stats;
};
struct mac_stx {
/* in_bad_octets */
u32 rx_stat_ifhcinbadoctets_hi;
u32 rx_stat_ifhcinbadoctets_lo;
/* out_bad_octets */
u32 tx_stat_ifhcoutbadoctets_hi;
u32 tx_stat_ifhcoutbadoctets_lo;
/* crc_receive_errors */
u32 rx_stat_dot3statsfcserrors_hi;
u32 rx_stat_dot3statsfcserrors_lo;
/* alignment_errors */
u32 rx_stat_dot3statsalignmenterrors_hi;
u32 rx_stat_dot3statsalignmenterrors_lo;
/* carrier_sense_errors */
u32 rx_stat_dot3statscarriersenseerrors_hi;
u32 rx_stat_dot3statscarriersenseerrors_lo;
/* false_carrier_detections */
u32 rx_stat_falsecarriererrors_hi;
u32 rx_stat_falsecarriererrors_lo;
/* runt_packets_received */
u32 rx_stat_etherstatsundersizepkts_hi;
u32 rx_stat_etherstatsundersizepkts_lo;
/* jabber_packets_received */
u32 rx_stat_dot3statsframestoolong_hi;
u32 rx_stat_dot3statsframestoolong_lo;
/* error_runt_packets_received */
u32 rx_stat_etherstatsfragments_hi;
u32 rx_stat_etherstatsfragments_lo;
/* error_jabber_packets_received */
u32 rx_stat_etherstatsjabbers_hi;
u32 rx_stat_etherstatsjabbers_lo;
/* control_frames_received */
u32 rx_stat_maccontrolframesreceived_hi;
u32 rx_stat_maccontrolframesreceived_lo;
u32 rx_stat_bmac_xpf_hi;
u32 rx_stat_bmac_xpf_lo;
u32 rx_stat_bmac_xcf_hi;
u32 rx_stat_bmac_xcf_lo;
/* xoff_state_entered */
u32 rx_stat_xoffstateentered_hi;
u32 rx_stat_xoffstateentered_lo;
/* pause_xon_frames_received */
u32 rx_stat_xonpauseframesreceived_hi;
u32 rx_stat_xonpauseframesreceived_lo;
/* pause_xoff_frames_received */
u32 rx_stat_xoffpauseframesreceived_hi;
u32 rx_stat_xoffpauseframesreceived_lo;
/* pause_xon_frames_transmitted */
u32 tx_stat_outxonsent_hi;
u32 tx_stat_outxonsent_lo;
/* pause_xoff_frames_transmitted */
u32 tx_stat_outxoffsent_hi;
u32 tx_stat_outxoffsent_lo;
/* flow_control_done */
u32 tx_stat_flowcontroldone_hi;
u32 tx_stat_flowcontroldone_lo;
/* ether_stats_collisions */
u32 tx_stat_etherstatscollisions_hi;
u32 tx_stat_etherstatscollisions_lo;
/* single_collision_transmit_frames */
u32 tx_stat_dot3statssinglecollisionframes_hi;
u32 tx_stat_dot3statssinglecollisionframes_lo;
/* multiple_collision_transmit_frames */
u32 tx_stat_dot3statsmultiplecollisionframes_hi;
u32 tx_stat_dot3statsmultiplecollisionframes_lo;
/* deferred_transmissions */
u32 tx_stat_dot3statsdeferredtransmissions_hi;
u32 tx_stat_dot3statsdeferredtransmissions_lo;
/* excessive_collision_frames */
u32 tx_stat_dot3statsexcessivecollisions_hi;
u32 tx_stat_dot3statsexcessivecollisions_lo;
/* late_collision_frames */
u32 tx_stat_dot3statslatecollisions_hi;
u32 tx_stat_dot3statslatecollisions_lo;
/* frames_transmitted_64_bytes */
u32 tx_stat_etherstatspkts64octets_hi;
u32 tx_stat_etherstatspkts64octets_lo;
/* frames_transmitted_65_127_bytes */
u32 tx_stat_etherstatspkts65octetsto127octets_hi;
u32 tx_stat_etherstatspkts65octetsto127octets_lo;
/* frames_transmitted_128_255_bytes */
u32 tx_stat_etherstatspkts128octetsto255octets_hi;
u32 tx_stat_etherstatspkts128octetsto255octets_lo;
/* frames_transmitted_256_511_bytes */
u32 tx_stat_etherstatspkts256octetsto511octets_hi;
u32 tx_stat_etherstatspkts256octetsto511octets_lo;
/* frames_transmitted_512_1023_bytes */
u32 tx_stat_etherstatspkts512octetsto1023octets_hi;
u32 tx_stat_etherstatspkts512octetsto1023octets_lo;
/* frames_transmitted_1024_1522_bytes */
u32 tx_stat_etherstatspkts1024octetsto1522octets_hi;
u32 tx_stat_etherstatspkts1024octetsto1522octets_lo;
/* frames_transmitted_1523_9022_bytes */
u32 tx_stat_etherstatspktsover1522octets_hi;
u32 tx_stat_etherstatspktsover1522octets_lo;
u32 tx_stat_bmac_2047_hi;
u32 tx_stat_bmac_2047_lo;
u32 tx_stat_bmac_4095_hi;
u32 tx_stat_bmac_4095_lo;
u32 tx_stat_bmac_9216_hi;
u32 tx_stat_bmac_9216_lo;
u32 tx_stat_bmac_16383_hi;
u32 tx_stat_bmac_16383_lo;
/* internal_mac_transmit_errors */
u32 tx_stat_dot3statsinternalmactransmiterrors_hi;
u32 tx_stat_dot3statsinternalmactransmiterrors_lo;
/* if_out_discards */
u32 tx_stat_bmac_ufl_hi;
u32 tx_stat_bmac_ufl_lo;
};
#define MAC_STX_IDX_MAX 2
struct host_port_stats {
u32 host_port_stats_start;
struct mac_stx mac_stx[MAC_STX_IDX_MAX];
u32 brb_drop_hi;
u32 brb_drop_lo;
u32 host_port_stats_end;
};
struct host_func_stats {
u32 host_func_stats_start;
u32 total_bytes_received_hi;
u32 total_bytes_received_lo;
u32 total_bytes_transmitted_hi;
u32 total_bytes_transmitted_lo;
u32 total_unicast_packets_received_hi;
u32 total_unicast_packets_received_lo;
u32 total_multicast_packets_received_hi;
u32 total_multicast_packets_received_lo;
u32 total_broadcast_packets_received_hi;
u32 total_broadcast_packets_received_lo;
u32 total_unicast_packets_transmitted_hi;
u32 total_unicast_packets_transmitted_lo;
u32 total_multicast_packets_transmitted_hi;
u32 total_multicast_packets_transmitted_lo;
u32 total_broadcast_packets_transmitted_hi;
u32 total_broadcast_packets_transmitted_lo;
u32 valid_bytes_received_hi;
u32 valid_bytes_received_lo;
u32 host_func_stats_end;
};
#define BCM_5710_FW_MAJOR_VERSION 4 #define BCM_5710_FW_MAJOR_VERSION 4
...@@ -2367,9 +2698,9 @@ struct cmng_struct_per_port { ...@@ -2367,9 +2698,9 @@ struct cmng_struct_per_port {
/* /*
* Common statistics collected by the Xstorm (per port) * Protocol-common statistics collected by the Xstorm (per client)
*/ */
struct xstorm_common_stats { struct xstorm_per_client_stats {
struct regpair total_sent_bytes; struct regpair total_sent_bytes;
u32 total_sent_pkts; u32 total_sent_pkts;
u32 unicast_pkts_sent; u32 unicast_pkts_sent;
...@@ -2378,9 +2709,31 @@ struct xstorm_common_stats { ...@@ -2378,9 +2709,31 @@ struct xstorm_common_stats {
u32 multicast_pkts_sent; u32 multicast_pkts_sent;
u32 broadcast_pkts_sent; u32 broadcast_pkts_sent;
struct regpair broadcast_bytes_sent; struct regpair broadcast_bytes_sent;
struct regpair done; u16 stats_counter;
u16 reserved0;
u32 reserved1;
}; };
/*
* Common statistics collected by the Xstorm (per port)
*/
struct xstorm_common_stats {
struct xstorm_per_client_stats client_statistics[MAX_X_STAT_COUNTER_ID];
};
/*
* Protocol-common statistics collected by the Tstorm (per port)
*/
struct tstorm_per_port_stats {
u32 mac_filter_discard;
u32 xxoverflow_discard;
u32 brb_truncate_discard;
u32 mac_discard;
};
/* /*
* Protocol-common statistics collected by the Tstorm (per client) * Protocol-common statistics collected by the Tstorm (per client)
*/ */
...@@ -2398,20 +2751,17 @@ struct tstorm_per_client_stats { ...@@ -2398,20 +2751,17 @@ struct tstorm_per_client_stats {
u32 rcv_multicast_pkts; u32 rcv_multicast_pkts;
u32 no_buff_discard; u32 no_buff_discard;
u32 ttl0_discard; u32 ttl0_discard;
u32 mac_discard; u16 stats_counter;
u32 reserved; u16 reserved0;
u32 reserved1;
}; };
/* /*
* Protocol-common statistics collected by the Tstorm (per port) * Protocol-common statistics collected by the Tstorm
*/ */
struct tstorm_common_stats { struct tstorm_common_stats {
struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID]; struct tstorm_per_port_stats port_statistics;
u32 mac_filter_discard; struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID];
u32 xxoverflow_discard;
u32 brb_truncate_discard;
u32 reserved;
struct regpair done;
}; };
/* /*
......
...@@ -568,8 +568,8 @@ static void bnx2x_panic_dump(struct bnx2x *bp) ...@@ -568,8 +568,8 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
bnx2x_mc_assert(bp); bnx2x_mc_assert(bp);
BNX2X_ERR("end crash dump -----------------\n"); BNX2X_ERR("end crash dump -----------------\n");
bp->stats_state = STATS_STATE_DISABLE; bp->stats_state = STATS_STATE_DISABLED;
DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n"); DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
} }
static void bnx2x_int_enable(struct bnx2x *bp) static void bnx2x_int_enable(struct bnx2x *bp)
...@@ -948,6 +948,7 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp, ...@@ -948,6 +948,7 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG): case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG):
DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
bp->set_mac_pending = 0;
break; break;
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT): case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
...@@ -1279,6 +1280,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) ...@@ -1279,6 +1280,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
/* end of fast path */ /* end of fast path */
static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event);
/* Link */ /* Link */
...@@ -1787,10 +1789,28 @@ static void bnx2x_link_attn(struct bnx2x *bp) ...@@ -1787,10 +1789,28 @@ static void bnx2x_link_attn(struct bnx2x *bp)
{ {
int vn; int vn;
/* Make sure that we are synced with the current statistics */
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
bnx2x_phy_hw_lock(bp); bnx2x_phy_hw_lock(bp);
bnx2x_link_update(&bp->link_params, &bp->link_vars); bnx2x_link_update(&bp->link_params, &bp->link_vars);
bnx2x_phy_hw_unlock(bp); bnx2x_phy_hw_unlock(bp);
if (bp->link_vars.link_up) {
if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
struct host_port_stats *pstats;
pstats = bnx2x_sp(bp, port_stats);
/* reset old bmac stats */
memset(&(pstats->mac_stx[0]), 0,
sizeof(struct mac_stx));
}
if ((bp->state == BNX2X_STATE_OPEN) ||
(bp->state == BNX2X_STATE_DISABLED))
bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
}
/* indicate link status */ /* indicate link status */
bnx2x_link_report(bp); bnx2x_link_report(bp);
...@@ -1835,6 +1855,11 @@ static void bnx2x__link_status_update(struct bnx2x *bp) ...@@ -1835,6 +1855,11 @@ static void bnx2x__link_status_update(struct bnx2x *bp)
bnx2x_link_status_update(&bp->link_params, &bp->link_vars); bnx2x_link_status_update(&bp->link_params, &bp->link_vars);
if (bp->link_vars.link_up)
bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
else
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
/* indicate link status */ /* indicate link status */
bnx2x_link_report(bp); bnx2x_link_report(bp);
} }
...@@ -1851,6 +1876,8 @@ static void bnx2x_pmf_update(struct bnx2x *bp) ...@@ -1851,6 +1876,8 @@ static void bnx2x_pmf_update(struct bnx2x *bp)
val = (0xff0f | (1 << (BP_E1HVN(bp) + 4))); val = (0xff0f | (1 << (BP_E1HVN(bp) + 4)));
REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
bnx2x_stats_handle(bp, STATS_EVENT_PMF);
} }
/* end of Link */ /* end of Link */
...@@ -2376,6 +2403,10 @@ static void bnx2x_sp_task(struct work_struct *work) ...@@ -2376,6 +2403,10 @@ static void bnx2x_sp_task(struct work_struct *work)
if (status & 0x1) if (status & 0x1)
bnx2x_attn_int(bp); bnx2x_attn_int(bp);
/* CStorm events: query_stats, port delete ramrod */
if (status & 0x2)
bp->stats_pending = 0;
bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, bp->def_att_idx, bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, bp->def_att_idx,
IGU_INT_NOP, 1); IGU_INT_NOP, 1);
bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx), bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx),
...@@ -2420,12 +2451,6 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) ...@@ -2420,12 +2451,6 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
* Macros * Macros
****************************************************************************/ ****************************************************************************/
#define UPDATE_STAT(s, t) \
do { \
estats->t += new->s - old->s; \
old->s = new->s; \
} while (0)
/* sum[hi:lo] += add[hi:lo] */ /* sum[hi:lo] += add[hi:lo] */
#define ADD_64(s_hi, a_hi, s_lo, a_lo) \ #define ADD_64(s_hi, a_hi, s_lo, a_lo) \
do { \ do { \
...@@ -2436,40 +2461,47 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) ...@@ -2436,40 +2461,47 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
/* difference = minuend - subtrahend */ /* difference = minuend - subtrahend */
#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \ #define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \
do { \ do { \
if (m_lo < s_lo) { /* underflow */ \ if (m_lo < s_lo) { \
/* underflow */ \
d_hi = m_hi - s_hi; \ d_hi = m_hi - s_hi; \
if (d_hi > 0) { /* we can 'loan' 1 */ \ if (d_hi > 0) { \
/* we can 'loan' 1 */ \
d_hi--; \ d_hi--; \
d_lo = m_lo + (UINT_MAX - s_lo) + 1; \ d_lo = m_lo + (UINT_MAX - s_lo) + 1; \
} else { /* m_hi <= s_hi */ \ } else { \
/* m_hi <= s_hi */ \
d_hi = 0; \ d_hi = 0; \
d_lo = 0; \ d_lo = 0; \
} \ } \
} else { /* m_lo >= s_lo */ \ } else { \
/* m_lo >= s_lo */ \
if (m_hi < s_hi) { \ if (m_hi < s_hi) { \
d_hi = 0; \ d_hi = 0; \
d_lo = 0; \ d_lo = 0; \
} else { /* m_hi >= s_hi */ \ } else { \
d_hi = m_hi - s_hi; \ /* m_hi >= s_hi */ \
d_lo = m_lo - s_lo; \ d_hi = m_hi - s_hi; \
d_lo = m_lo - s_lo; \
} \ } \
} \ } \
} while (0) } while (0)
/* minuend -= subtrahend */ #define UPDATE_STAT64(s, t) \
#define SUB_64(m_hi, s_hi, m_lo, s_lo) \
do { \ do { \
DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \ DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \
diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \
pstats->mac_stx[0].t##_hi = new->s##_hi; \
pstats->mac_stx[0].t##_lo = new->s##_lo; \
ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \
pstats->mac_stx[1].t##_lo, diff.lo); \
} while (0) } while (0)
#define UPDATE_STAT64(s_hi, t_hi, s_lo, t_lo) \ #define UPDATE_STAT64_NIG(s, t) \
do { \ do { \
DIFF_64(diff.hi, new->s_hi, old->s_hi, \ DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \
diff.lo, new->s_lo, old->s_lo); \ diff.lo, new->s##_lo, old->s##_lo); \
old->s_hi = new->s_hi; \ ADD_64(estats->t##_hi, diff.hi, \
old->s_lo = new->s_lo; \ estats->t##_lo, diff.lo); \
ADD_64(estats->t_hi, diff.hi, \
estats->t_lo, diff.lo); \
} while (0) } while (0)
/* sum[hi:lo] += add */ /* sum[hi:lo] += add */
...@@ -2479,16 +2511,25 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) ...@@ -2479,16 +2511,25 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
s_hi += (s_lo < a) ? 1 : 0; \ s_hi += (s_lo < a) ? 1 : 0; \
} while (0) } while (0)
#define UPDATE_EXTEND_STAT(s, t_hi, t_lo) \ #define UPDATE_EXTEND_STAT(s) \
do { \ do { \
ADD_EXTEND_64(estats->t_hi, estats->t_lo, new->s); \ ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \
pstats->mac_stx[1].s##_lo, \
new->s); \
} while (0) } while (0)
#define UPDATE_EXTEND_TSTAT(s, t_hi, t_lo) \ #define UPDATE_EXTEND_TSTAT(s, t) \
do { \ do { \
diff = le32_to_cpu(tclient->s) - old_tclient->s; \ diff = le32_to_cpu(tclient->s) - old_tclient->s; \
old_tclient->s = le32_to_cpu(tclient->s); \ old_tclient->s = le32_to_cpu(tclient->s); \
ADD_EXTEND_64(estats->t_hi, estats->t_lo, diff); \ ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
} while (0)
#define UPDATE_EXTEND_XSTAT(s, t) \
do { \
diff = le32_to_cpu(xclient->s) - old_xclient->s; \
old_xclient->s = le32_to_cpu(xclient->s); \
ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
} while (0) } while (0)
/* /*
...@@ -2511,55 +2552,272 @@ static inline long bnx2x_hilo(u32 *hiref) ...@@ -2511,55 +2552,272 @@ static inline long bnx2x_hilo(u32 *hiref)
* Init service functions * Init service functions
*/ */
static void bnx2x_init_mac_stats(struct bnx2x *bp) static void bnx2x_storm_stats_init(struct bnx2x *bp)
{
int func = BP_FUNC(bp);
REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func), 1);
REG_WR(bp, BAR_XSTRORM_INTMEM +
XSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func), 1);
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func), 0);
REG_WR(bp, BAR_CSTRORM_INTMEM +
CSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
REG_WR(bp, BAR_XSTRORM_INTMEM +
XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
REG_WR(bp, BAR_XSTRORM_INTMEM +
XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
}
static void bnx2x_storm_stats_post(struct bnx2x *bp)
{
if (!bp->stats_pending) {
struct eth_query_ramrod_data ramrod_data = {0};
int rc;
ramrod_data.drv_counter = bp->stats_counter++;
ramrod_data.collect_port_1b = bp->port.pmf ? 1 : 0;
ramrod_data.ctr_id_vector = (1 << BP_CL_ID(bp));
rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0,
((u32 *)&ramrod_data)[1],
((u32 *)&ramrod_data)[0], 0);
if (rc == 0) {
/* stats ramrod has it's own slot on the spq */
bp->spq_left++;
bp->stats_pending = 1;
}
}
}
static void bnx2x_stats_init(struct bnx2x *bp)
{
int port = BP_PORT(bp);
bp->executer_idx = 0;
bp->stats_counter = 0;
/* port stats */
if (!BP_NOMCP(bp))
bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx);
else
bp->port.port_stx = 0;
DP(BNX2X_MSG_STATS, "port_stx 0x%x\n", bp->port.port_stx);
memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats));
bp->port.old_nig_stats.brb_discard =
REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
&(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2);
REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
&(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
/* function stats */
memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats));
memset(&bp->old_xclient, 0, sizeof(struct xstorm_per_client_stats));
memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
bp->stats_state = STATS_STATE_DISABLED;
if (IS_E1HMF(bp) && bp->port.pmf && bp->port.port_stx)
bnx2x_stats_handle(bp, STATS_EVENT_PMF);
}
static void bnx2x_hw_stats_post(struct bnx2x *bp)
{
struct dmae_command *dmae = &bp->stats_dmae;
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
*stats_comp = DMAE_COMP_VAL;
/* loader */
if (bp->executer_idx) {
int loader_idx = PMF_DMAE_C(bp);
memset(dmae, 0, sizeof(struct dmae_command));
dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
DMAE_CMD_DST_RESET |
#ifdef __BIG_ENDIAN
DMAE_CMD_ENDIANITY_B_DW_SWAP |
#else
DMAE_CMD_ENDIANITY_DW_SWAP |
#endif
(BP_PORT(bp) ? DMAE_CMD_PORT_1 :
DMAE_CMD_PORT_0) |
(BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0]));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0]));
dmae->dst_addr_lo = (DMAE_REG_CMD_MEM +
sizeof(struct dmae_command) *
(loader_idx + 1)) >> 2;
dmae->dst_addr_hi = 0;
dmae->len = sizeof(struct dmae_command) >> 2;
if (CHIP_IS_E1(bp))
dmae->len--;
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2;
dmae->comp_addr_hi = 0;
dmae->comp_val = 1;
*stats_comp = 0;
bnx2x_post_dmae(bp, dmae, loader_idx);
} else if (bp->func_stx) {
*stats_comp = 0;
bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
}
}
static int bnx2x_stats_comp(struct bnx2x *bp)
{
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
int cnt = 10;
might_sleep();
while (*stats_comp != DMAE_COMP_VAL) {
msleep(1);
if (!cnt) {
BNX2X_ERR("timeout waiting for stats finished\n");
break;
}
cnt--;
}
return 1;
}
/*
* Statistics service functions
*/
static void bnx2x_stats_pmf_update(struct bnx2x *bp)
{
struct dmae_command *dmae;
u32 opcode;
int loader_idx = PMF_DMAE_C(bp);
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
/* sanity */
if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) {
BNX2X_ERR("BUG!\n");
return;
}
bp->executer_idx = 0;
opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
DMAE_CMD_C_ENABLE |
DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
#ifdef __BIG_ENDIAN
DMAE_CMD_ENDIANITY_B_DW_SWAP |
#else
DMAE_CMD_ENDIANITY_DW_SWAP |
#endif
(BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
(BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
dmae->src_addr_lo = bp->port.port_stx >> 2;
dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
dmae->len = DMAE_LEN32_RD_MAX;
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
dmae->comp_addr_hi = 0;
dmae->comp_val = 1;
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX;
dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)
+ DMAE_LEN32_RD_MAX * 4);
dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)
+ DMAE_LEN32_RD_MAX * 4);
dmae->len = (sizeof(struct host_port_stats) >> 2) - DMAE_LEN32_RD_MAX;
dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
dmae->comp_val = DMAE_COMP_VAL;
*stats_comp = 0;
bnx2x_hw_stats_post(bp);
bnx2x_stats_comp(bp);
}
static void bnx2x_port_stats_init(struct bnx2x *bp)
{ {
struct dmae_command *dmae; struct dmae_command *dmae;
int port = BP_PORT(bp); int port = BP_PORT(bp);
int loader_idx = port * 8; int vn = BP_E1HVN(bp);
u32 opcode; u32 opcode;
int loader_idx = PMF_DMAE_C(bp);
u32 mac_addr; u32 mac_addr;
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
/* sanity */
if (!bp->link_vars.link_up || !bp->port.pmf) {
BNX2X_ERR("BUG!\n");
return;
}
bp->executer_idx = 0; bp->executer_idx = 0;
if (bp->func_stx) {
/* MCP */ /* MCP */
opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
DMAE_CMD_ENDIANITY_B_DW_SWAP | DMAE_CMD_ENDIANITY_B_DW_SWAP |
#else #else
DMAE_CMD_ENDIANITY_DW_SWAP | DMAE_CMD_ENDIANITY_DW_SWAP |
#endif #endif
(port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
(vn << DMAE_CMD_E1HVN_SHIFT));
if (bp->link_vars.link_up) if (bp->port.port_stx) {
opcode |= (DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE);
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
dmae->opcode = opcode; dmae->opcode = opcode;
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, eth_stats) + dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
sizeof(u32)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, eth_stats) + dmae->dst_addr_lo = bp->port.port_stx >> 2;
sizeof(u32));
dmae->dst_addr_lo = bp->func_stx >> 2;
dmae->dst_addr_hi = 0; dmae->dst_addr_hi = 0;
dmae->len = (offsetof(struct bnx2x_eth_stats, mac_stx_end) - dmae->len = sizeof(struct host_port_stats) >> 2;
sizeof(u32)) >> 2; dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
if (bp->link_vars.link_up) { dmae->comp_addr_hi = 0;
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_val = 1;
dmae->comp_addr_hi = 0;
dmae->comp_val = 1;
} else {
dmae->comp_addr_lo = 0;
dmae->comp_addr_hi = 0;
dmae->comp_val = 0;
}
} }
if (!bp->link_vars.link_up) { if (bp->func_stx) {
/* no need to collect statistics in link down */
return; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
dmae->opcode = opcode;
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
dmae->dst_addr_lo = bp->func_stx >> 2;
dmae->dst_addr_hi = 0;
dmae->len = sizeof(struct host_func_stats) >> 2;
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
dmae->comp_addr_hi = 0;
dmae->comp_val = 1;
} }
/* MAC */
opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
...@@ -2568,7 +2826,8 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp) ...@@ -2568,7 +2826,8 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
#else #else
DMAE_CMD_ENDIANITY_DW_SWAP | DMAE_CMD_ENDIANITY_DW_SWAP |
#endif #endif
(port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
(vn << DMAE_CMD_E1HVN_SHIFT));
if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
...@@ -2598,9 +2857,9 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp) ...@@ -2598,9 +2857,9 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
BIGMAC_REGISTER_RX_STAT_GR64) >> 2; BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
dmae->src_addr_hi = 0; dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
offsetof(struct bmac_stats, rx_gr64)); offsetof(struct bmac_stats, rx_stat_gr64_lo));
dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
offsetof(struct bmac_stats, rx_gr64)); offsetof(struct bmac_stats, rx_stat_gr64_lo));
dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
BIGMAC_REGISTER_RX_STAT_GR64) >> 2; BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
...@@ -2631,11 +2890,9 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp) ...@@ -2631,11 +2890,9 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
EMAC_REG_EMAC_RX_STAT_AC_28) >> 2; EMAC_REG_EMAC_RX_STAT_AC_28) >> 2;
dmae->src_addr_hi = 0; dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
offsetof(struct emac_stats, offsetof(struct emac_stats, rx_stat_falsecarriererrors));
rx_falsecarriererrors));
dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
offsetof(struct emac_stats, offsetof(struct emac_stats, rx_stat_falsecarriererrors));
rx_falsecarriererrors));
dmae->len = 1; dmae->len = 1;
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
dmae->comp_addr_hi = 0; dmae->comp_addr_hi = 0;
...@@ -2648,11 +2905,9 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp) ...@@ -2648,11 +2905,9 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
EMAC_REG_EMAC_TX_STAT_AC) >> 2; EMAC_REG_EMAC_TX_STAT_AC) >> 2;
dmae->src_addr_hi = 0; dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
offsetof(struct emac_stats, offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
tx_ifhcoutoctets));
dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
offsetof(struct emac_stats, offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
tx_ifhcoutoctets));
dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT; dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT;
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
dmae->comp_addr_hi = 0; dmae->comp_addr_hi = 0;
...@@ -2660,6 +2915,32 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp) ...@@ -2660,6 +2915,32 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
} }
/* NIG */ /* NIG */
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
dmae->opcode = opcode;
dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD :
NIG_REG_STAT0_BRB_DISCARD) >> 2;
dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats));
dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats));
dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2;
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
dmae->comp_addr_hi = 0;
dmae->comp_val = 1;
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
dmae->opcode = opcode;
dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 :
NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2;
dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
offsetof(struct nig_stats, egress_mac_pkt0_lo));
dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
offsetof(struct nig_stats, egress_mac_pkt0_lo));
dmae->len = (2*sizeof(u32)) >> 2;
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
dmae->comp_addr_hi = 0;
dmae->comp_val = 1;
dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
...@@ -2669,325 +2950,322 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp) ...@@ -2669,325 +2950,322 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp)
#else #else
DMAE_CMD_ENDIANITY_DW_SWAP | DMAE_CMD_ENDIANITY_DW_SWAP |
#endif #endif
(port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD : (vn << DMAE_CMD_E1HVN_SHIFT));
NIG_REG_STAT0_BRB_DISCARD) >> 2; dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 :
NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2;
dmae->src_addr_hi = 0; dmae->src_addr_hi = 0;
dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig)); dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig)); offsetof(struct nig_stats, egress_mac_pkt1_lo));
dmae->len = (sizeof(struct nig_stats) - 2*sizeof(u32)) >> 2; dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig) + offsetof(struct nig_stats, egress_mac_pkt1_lo));
offsetof(struct nig_stats, done)); dmae->len = (2*sizeof(u32)) >> 2;
dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig) + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
offsetof(struct nig_stats, done)); dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
dmae->comp_val = 0xffffffff; dmae->comp_val = DMAE_COMP_VAL;
*stats_comp = 0;
} }
static void bnx2x_init_stats(struct bnx2x *bp) static void bnx2x_func_stats_init(struct bnx2x *bp)
{ {
int port = BP_PORT(bp); struct dmae_command *dmae = &bp->stats_dmae;
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
bp->stats_state = STATS_STATE_DISABLE; /* sanity */
bp->executer_idx = 0; if (!bp->func_stx) {
BNX2X_ERR("BUG!\n");
return;
}
bp->old_brb_discard = REG_RD(bp, bp->executer_idx = 0;
NIG_REG_STAT0_BRB_DISCARD + port*0x38); memset(dmae, 0, sizeof(struct dmae_command));
memset(&bp->old_bmac, 0, sizeof(struct bmac_stats)); dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats)); DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
#ifdef __BIG_ENDIAN
DMAE_CMD_ENDIANITY_B_DW_SWAP |
#else
DMAE_CMD_ENDIANITY_DW_SWAP |
#endif
(BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
(BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
dmae->dst_addr_lo = bp->func_stx >> 2;
dmae->dst_addr_hi = 0;
dmae->len = sizeof(struct host_func_stats) >> 2;
dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
dmae->comp_val = DMAE_COMP_VAL;
REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port), 1); *stats_comp = 0;
REG_WR(bp, BAR_XSTRORM_INTMEM + }
XSTORM_STATS_FLAGS_OFFSET(port) + 4, 0);
REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port), 1); static void bnx2x_stats_start(struct bnx2x *bp)
REG_WR(bp, BAR_TSTRORM_INTMEM + {
TSTORM_STATS_FLAGS_OFFSET(port) + 4, 0); if (bp->port.pmf)
bnx2x_port_stats_init(bp);
else if (bp->func_stx)
bnx2x_func_stats_init(bp);
bnx2x_hw_stats_post(bp);
bnx2x_storm_stats_post(bp);
}
static void bnx2x_stats_pmf_start(struct bnx2x *bp)
{
bnx2x_stats_comp(bp);
bnx2x_stats_pmf_update(bp);
bnx2x_stats_start(bp);
}
static void bnx2x_stats_restart(struct bnx2x *bp)
{
bnx2x_stats_comp(bp);
bnx2x_stats_start(bp);
}
static void bnx2x_bmac_stats_update(struct bnx2x *bp)
{
struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats);
struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
struct regpair diff;
UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf);
UPDATE_STAT64(rx_stat_grxcf, rx_stat_bmac_xcf);
UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffpauseframesreceived);
UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
UPDATE_STAT64(tx_stat_gt127,
tx_stat_etherstatspkts65octetsto127octets);
UPDATE_STAT64(tx_stat_gt255,
tx_stat_etherstatspkts128octetsto255octets);
UPDATE_STAT64(tx_stat_gt511,
tx_stat_etherstatspkts256octetsto511octets);
UPDATE_STAT64(tx_stat_gt1023,
tx_stat_etherstatspkts512octetsto1023octets);
UPDATE_STAT64(tx_stat_gt1518,
tx_stat_etherstatspkts1024octetsto1522octets);
UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047);
UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095);
UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216);
UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383);
UPDATE_STAT64(tx_stat_gterr,
tx_stat_dot3statsinternalmactransmiterrors);
UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
}
static void bnx2x_emac_stats_update(struct bnx2x *bp)
{
struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats);
struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors);
UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors);
UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors);
UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors);
UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts);
UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong);
UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments);
UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers);
UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived);
UPDATE_EXTEND_STAT(rx_stat_xoffstateentered);
UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived);
UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived);
UPDATE_EXTEND_STAT(tx_stat_outxonsent);
UPDATE_EXTEND_STAT(tx_stat_outxoffsent);
UPDATE_EXTEND_STAT(tx_stat_flowcontroldone);
UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions);
UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes);
UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes);
UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions);
UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions);
UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions);
UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets);
UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets);
UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets);
UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets);
UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets);
UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
}
static int bnx2x_hw_stats_update(struct bnx2x *bp)
{
struct nig_stats *new = bnx2x_sp(bp, nig_stats);
struct nig_stats *old = &(bp->port.old_nig_stats);
struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
struct bnx2x_eth_stats *estats = &bp->eth_stats;
struct regpair diff;
if (bp->link_vars.mac_type == MAC_TYPE_BMAC)
bnx2x_bmac_stats_update(bp);
else if (bp->link_vars.mac_type == MAC_TYPE_EMAC)
bnx2x_emac_stats_update(bp);
else { /* unreached */
BNX2X_ERR("stats updated by dmae but no MAC active\n");
return -1;
}
REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port), 0); ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo,
REG_WR(bp, BAR_CSTRORM_INTMEM + new->brb_discard - old->brb_discard);
CSTORM_STATS_FLAGS_OFFSET(port) + 4, 0);
REG_WR(bp, BAR_XSTRORM_INTMEM + UPDATE_STAT64_NIG(egress_mac_pkt0,
XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port), etherstatspkts1024octetsto1522octets);
U64_LO(bnx2x_sp_mapping(bp, fw_stats))); UPDATE_STAT64_NIG(egress_mac_pkt1, etherstatspktsover1522octets);
REG_WR(bp, BAR_XSTRORM_INTMEM +
XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port) + 4,
U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
REG_WR(bp, BAR_TSTRORM_INTMEM + memcpy(old, new, sizeof(struct nig_stats));
TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port),
U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port) + 4,
U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
}
static void bnx2x_stop_stats(struct bnx2x *bp) memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]),
{ sizeof(struct mac_stx));
might_sleep(); estats->brb_drop_hi = pstats->brb_drop_hi;
if (bp->stats_state != STATS_STATE_DISABLE) { estats->brb_drop_lo = pstats->brb_drop_lo;
int timeout = 10;
bp->stats_state = STATS_STATE_STOP; pstats->host_port_stats_start = ++pstats->host_port_stats_end;
DP(BNX2X_MSG_STATS, "stats_state - STOP\n");
while (bp->stats_state != STATS_STATE_DISABLE) { return 0;
if (!timeout) {
BNX2X_ERR("timeout waiting for stats stop\n");
break;
}
timeout--;
msleep(100);
}
}
DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n");
} }
/* static int bnx2x_storm_stats_update(struct bnx2x *bp)
* Statistics service functions
*/
static void bnx2x_update_bmac_stats(struct bnx2x *bp)
{
struct regp diff;
struct regp sum;
struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac);
struct bmac_stats *old = &bp->old_bmac;
struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
sum.hi = 0;
sum.lo = 0;
UPDATE_STAT64(tx_gtbyt.hi, total_bytes_transmitted_hi,
tx_gtbyt.lo, total_bytes_transmitted_lo);
UPDATE_STAT64(tx_gtmca.hi, total_multicast_packets_transmitted_hi,
tx_gtmca.lo, total_multicast_packets_transmitted_lo);
ADD_64(sum.hi, diff.hi, sum.lo, diff.lo);
UPDATE_STAT64(tx_gtgca.hi, total_broadcast_packets_transmitted_hi,
tx_gtgca.lo, total_broadcast_packets_transmitted_lo);
ADD_64(sum.hi, diff.hi, sum.lo, diff.lo);
UPDATE_STAT64(tx_gtpkt.hi, total_unicast_packets_transmitted_hi,
tx_gtpkt.lo, total_unicast_packets_transmitted_lo);
SUB_64(estats->total_unicast_packets_transmitted_hi, sum.hi,
estats->total_unicast_packets_transmitted_lo, sum.lo);
UPDATE_STAT(tx_gtxpf.lo, pause_xoff_frames_transmitted);
UPDATE_STAT(tx_gt64.lo, frames_transmitted_64_bytes);
UPDATE_STAT(tx_gt127.lo, frames_transmitted_65_127_bytes);
UPDATE_STAT(tx_gt255.lo, frames_transmitted_128_255_bytes);
UPDATE_STAT(tx_gt511.lo, frames_transmitted_256_511_bytes);
UPDATE_STAT(tx_gt1023.lo, frames_transmitted_512_1023_bytes);
UPDATE_STAT(tx_gt1518.lo, frames_transmitted_1024_1522_bytes);
UPDATE_STAT(tx_gt2047.lo, frames_transmitted_1523_9022_bytes);
UPDATE_STAT(tx_gt4095.lo, frames_transmitted_1523_9022_bytes);
UPDATE_STAT(tx_gt9216.lo, frames_transmitted_1523_9022_bytes);
UPDATE_STAT(tx_gt16383.lo, frames_transmitted_1523_9022_bytes);
UPDATE_STAT(rx_grfcs.lo, crc_receive_errors);
UPDATE_STAT(rx_grund.lo, runt_packets_received);
UPDATE_STAT(rx_grovr.lo, stat_Dot3statsFramesTooLong);
UPDATE_STAT(rx_grxpf.lo, pause_xoff_frames_received);
UPDATE_STAT(rx_grxcf.lo, control_frames_received);
/* UPDATE_STAT(rx_grxpf.lo, control_frames_received); */
UPDATE_STAT(rx_grfrg.lo, error_runt_packets_received);
UPDATE_STAT(rx_grjbr.lo, error_jabber_packets_received);
UPDATE_STAT64(rx_grerb.hi, stat_IfHCInBadOctets_hi,
rx_grerb.lo, stat_IfHCInBadOctets_lo);
UPDATE_STAT64(tx_gtufl.hi, stat_IfHCOutBadOctets_hi,
tx_gtufl.lo, stat_IfHCOutBadOctets_lo);
UPDATE_STAT(tx_gterr.lo, stat_Dot3statsInternalMacTransmitErrors);
/* UPDATE_STAT(rx_grxpf.lo, stat_XoffStateEntered); */
estats->stat_XoffStateEntered = estats->pause_xoff_frames_received;
}
static void bnx2x_update_emac_stats(struct bnx2x *bp)
{
struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac);
struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
UPDATE_EXTEND_STAT(tx_ifhcoutoctets, total_bytes_transmitted_hi,
total_bytes_transmitted_lo);
UPDATE_EXTEND_STAT(tx_ifhcoutucastpkts,
total_unicast_packets_transmitted_hi,
total_unicast_packets_transmitted_lo);
UPDATE_EXTEND_STAT(tx_ifhcoutmulticastpkts,
total_multicast_packets_transmitted_hi,
total_multicast_packets_transmitted_lo);
UPDATE_EXTEND_STAT(tx_ifhcoutbroadcastpkts,
total_broadcast_packets_transmitted_hi,
total_broadcast_packets_transmitted_lo);
estats->pause_xon_frames_transmitted += new->tx_outxonsent;
estats->pause_xoff_frames_transmitted += new->tx_outxoffsent;
estats->single_collision_transmit_frames +=
new->tx_dot3statssinglecollisionframes;
estats->multiple_collision_transmit_frames +=
new->tx_dot3statsmultiplecollisionframes;
estats->late_collision_frames += new->tx_dot3statslatecollisions;
estats->excessive_collision_frames +=
new->tx_dot3statsexcessivecollisions;
estats->frames_transmitted_64_bytes += new->tx_etherstatspkts64octets;
estats->frames_transmitted_65_127_bytes +=
new->tx_etherstatspkts65octetsto127octets;
estats->frames_transmitted_128_255_bytes +=
new->tx_etherstatspkts128octetsto255octets;
estats->frames_transmitted_256_511_bytes +=
new->tx_etherstatspkts256octetsto511octets;
estats->frames_transmitted_512_1023_bytes +=
new->tx_etherstatspkts512octetsto1023octets;
estats->frames_transmitted_1024_1522_bytes +=
new->tx_etherstatspkts1024octetsto1522octet;
estats->frames_transmitted_1523_9022_bytes +=
new->tx_etherstatspktsover1522octets;
estats->crc_receive_errors += new->rx_dot3statsfcserrors;
estats->alignment_errors += new->rx_dot3statsalignmenterrors;
estats->false_carrier_detections += new->rx_falsecarriererrors;
estats->runt_packets_received += new->rx_etherstatsundersizepkts;
estats->stat_Dot3statsFramesTooLong += new->rx_dot3statsframestoolong;
estats->pause_xon_frames_received += new->rx_xonpauseframesreceived;
estats->pause_xoff_frames_received += new->rx_xoffpauseframesreceived;
estats->control_frames_received += new->rx_maccontrolframesreceived;
estats->error_runt_packets_received += new->rx_etherstatsfragments;
estats->error_jabber_packets_received += new->rx_etherstatsjabbers;
UPDATE_EXTEND_STAT(rx_ifhcinbadoctets, stat_IfHCInBadOctets_hi,
stat_IfHCInBadOctets_lo);
UPDATE_EXTEND_STAT(tx_ifhcoutbadoctets, stat_IfHCOutBadOctets_hi,
stat_IfHCOutBadOctets_lo);
estats->stat_Dot3statsInternalMacTransmitErrors +=
new->tx_dot3statsinternalmactransmiterrors;
estats->stat_Dot3StatsCarrierSenseErrors +=
new->rx_dot3statscarriersenseerrors;
estats->stat_Dot3StatsDeferredTransmissions +=
new->tx_dot3statsdeferredtransmissions;
estats->stat_FlowControlDone += new->tx_flowcontroldone;
estats->stat_XoffStateEntered += new->rx_xoffstateentered;
}
static int bnx2x_update_storm_stats(struct bnx2x *bp)
{ {
struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
struct tstorm_common_stats *tstats = &stats->tstorm_common; int cl_id = BP_CL_ID(bp);
struct tstorm_per_port_stats *tport =
&stats->tstorm_common.port_statistics;
struct tstorm_per_client_stats *tclient = struct tstorm_per_client_stats *tclient =
&tstats->client_statistics[0]; &stats->tstorm_common.client_statistics[cl_id];
struct tstorm_per_client_stats *old_tclient = &bp->old_tclient; struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
struct xstorm_common_stats *xstats = &stats->xstorm_common; struct xstorm_per_client_stats *xclient =
struct nig_stats *nstats = bnx2x_sp(bp, nig); &stats->xstorm_common.client_statistics[cl_id];
struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); struct xstorm_per_client_stats *old_xclient = &bp->old_xclient;
struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
struct bnx2x_eth_stats *estats = &bp->eth_stats;
u32 diff; u32 diff;
/* are DMAE stats valid? */ /* are storm stats valid? */
if (nstats->done != 0xffffffff) { if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
DP(BNX2X_MSG_STATS, "stats not updated by dmae\n"); bp->stats_counter) {
DP(BNX2X_MSG_STATS, "stats not updated by tstorm"
" tstorm counter (%d) != stats_counter (%d)\n",
tclient->stats_counter, bp->stats_counter);
return -1; return -1;
} }
if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
/* are storm stats valid? */ bp->stats_counter) {
if (tstats->done.hi != 0xffffffff) { DP(BNX2X_MSG_STATS, "stats not updated by xstorm"
DP(BNX2X_MSG_STATS, "stats not updated by tstorm\n"); " xstorm counter (%d) != stats_counter (%d)\n",
xclient->stats_counter, bp->stats_counter);
return -2; return -2;
} }
if (xstats->done.hi != 0xffffffff) {
DP(BNX2X_MSG_STATS, "stats not updated by xstorm\n");
return -3;
}
estats->total_bytes_received_hi = fstats->total_bytes_received_hi =
estats->valid_bytes_received_hi = fstats->valid_bytes_received_hi =
le32_to_cpu(tclient->total_rcv_bytes.hi); le32_to_cpu(tclient->total_rcv_bytes.hi);
estats->total_bytes_received_lo = fstats->total_bytes_received_lo =
estats->valid_bytes_received_lo = fstats->valid_bytes_received_lo =
le32_to_cpu(tclient->total_rcv_bytes.lo); le32_to_cpu(tclient->total_rcv_bytes.lo);
ADD_64(estats->total_bytes_received_hi,
le32_to_cpu(tclient->rcv_error_bytes.hi), estats->error_bytes_received_hi =
estats->total_bytes_received_lo, le32_to_cpu(tclient->rcv_error_bytes.hi);
le32_to_cpu(tclient->rcv_error_bytes.lo)); estats->error_bytes_received_lo =
le32_to_cpu(tclient->rcv_error_bytes.lo);
UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, ADD_64(estats->error_bytes_received_hi,
total_unicast_packets_received_hi, estats->rx_stat_ifhcinbadoctets_hi,
total_unicast_packets_received_lo); estats->error_bytes_received_lo,
estats->rx_stat_ifhcinbadoctets_lo);
ADD_64(fstats->total_bytes_received_hi,
estats->error_bytes_received_hi,
fstats->total_bytes_received_lo,
estats->error_bytes_received_lo);
UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, total_unicast_packets_received);
UPDATE_EXTEND_TSTAT(rcv_multicast_pkts, UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
total_multicast_packets_received_hi, total_multicast_packets_received);
total_multicast_packets_received_lo);
UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts, UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
total_broadcast_packets_received_hi, total_broadcast_packets_received);
total_broadcast_packets_received_lo);
fstats->total_bytes_transmitted_hi =
estats->frames_received_64_bytes = MAC_STX_NA; le32_to_cpu(xclient->total_sent_bytes.hi);
estats->frames_received_65_127_bytes = MAC_STX_NA; fstats->total_bytes_transmitted_lo =
estats->frames_received_128_255_bytes = MAC_STX_NA; le32_to_cpu(xclient->total_sent_bytes.lo);
estats->frames_received_256_511_bytes = MAC_STX_NA;
estats->frames_received_512_1023_bytes = MAC_STX_NA; UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
estats->frames_received_1024_1522_bytes = MAC_STX_NA; total_unicast_packets_transmitted);
estats->frames_received_1523_9022_bytes = MAC_STX_NA; UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
total_multicast_packets_transmitted);
estats->x_total_sent_bytes_hi = UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
le32_to_cpu(xstats->total_sent_bytes.hi); total_broadcast_packets_transmitted);
estats->x_total_sent_bytes_lo =
le32_to_cpu(xstats->total_sent_bytes.lo); memcpy(estats, &(fstats->total_bytes_received_hi),
estats->x_total_sent_pkts = le32_to_cpu(xstats->total_sent_pkts); sizeof(struct host_func_stats) - 2*sizeof(u32));
estats->t_rcv_unicast_bytes_hi = estats->mac_filter_discard = le32_to_cpu(tport->mac_filter_discard);
estats->xxoverflow_discard = le32_to_cpu(tport->xxoverflow_discard);
estats->brb_truncate_discard =
le32_to_cpu(tport->brb_truncate_discard);
estats->mac_discard = le32_to_cpu(tport->mac_discard);
old_tclient->rcv_unicast_bytes.hi =
le32_to_cpu(tclient->rcv_unicast_bytes.hi); le32_to_cpu(tclient->rcv_unicast_bytes.hi);
estats->t_rcv_unicast_bytes_lo = old_tclient->rcv_unicast_bytes.lo =
le32_to_cpu(tclient->rcv_unicast_bytes.lo); le32_to_cpu(tclient->rcv_unicast_bytes.lo);
estats->t_rcv_broadcast_bytes_hi = old_tclient->rcv_broadcast_bytes.hi =
le32_to_cpu(tclient->rcv_broadcast_bytes.hi); le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
estats->t_rcv_broadcast_bytes_lo = old_tclient->rcv_broadcast_bytes.lo =
le32_to_cpu(tclient->rcv_broadcast_bytes.lo); le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
estats->t_rcv_multicast_bytes_hi = old_tclient->rcv_multicast_bytes.hi =
le32_to_cpu(tclient->rcv_multicast_bytes.hi); le32_to_cpu(tclient->rcv_multicast_bytes.hi);
estats->t_rcv_multicast_bytes_lo = old_tclient->rcv_multicast_bytes.lo =
le32_to_cpu(tclient->rcv_multicast_bytes.lo); le32_to_cpu(tclient->rcv_multicast_bytes.lo);
estats->t_total_rcv_pkt = le32_to_cpu(tclient->total_rcv_pkts); old_tclient->total_rcv_pkts = le32_to_cpu(tclient->total_rcv_pkts);
estats->checksum_discard = le32_to_cpu(tclient->checksum_discard); old_tclient->checksum_discard = le32_to_cpu(tclient->checksum_discard);
estats->packets_too_big_discard = old_tclient->packets_too_big_discard =
le32_to_cpu(tclient->packets_too_big_discard); le32_to_cpu(tclient->packets_too_big_discard);
estats->jabber_packets_received = estats->packets_too_big_discard + estats->no_buff_discard =
estats->stat_Dot3statsFramesTooLong; old_tclient->no_buff_discard = le32_to_cpu(tclient->no_buff_discard);
estats->no_buff_discard = le32_to_cpu(tclient->no_buff_discard); old_tclient->ttl0_discard = le32_to_cpu(tclient->ttl0_discard);
estats->ttl0_discard = le32_to_cpu(tclient->ttl0_discard);
estats->mac_discard = le32_to_cpu(tclient->mac_discard); old_xclient->total_sent_pkts = le32_to_cpu(xclient->total_sent_pkts);
estats->mac_filter_discard = le32_to_cpu(tstats->mac_filter_discard); old_xclient->unicast_bytes_sent.hi =
estats->xxoverflow_discard = le32_to_cpu(tstats->xxoverflow_discard); le32_to_cpu(xclient->unicast_bytes_sent.hi);
estats->brb_truncate_discard = old_xclient->unicast_bytes_sent.lo =
le32_to_cpu(tstats->brb_truncate_discard); le32_to_cpu(xclient->unicast_bytes_sent.lo);
old_xclient->multicast_bytes_sent.hi =
estats->brb_discard += nstats->brb_discard - bp->old_brb_discard; le32_to_cpu(xclient->multicast_bytes_sent.hi);
bp->old_brb_discard = nstats->brb_discard; old_xclient->multicast_bytes_sent.lo =
le32_to_cpu(xclient->multicast_bytes_sent.lo);
estats->brb_packet = nstats->brb_packet; old_xclient->broadcast_bytes_sent.hi =
estats->brb_truncate = nstats->brb_truncate; le32_to_cpu(xclient->broadcast_bytes_sent.hi);
estats->flow_ctrl_discard = nstats->flow_ctrl_discard; old_xclient->broadcast_bytes_sent.lo =
estats->flow_ctrl_octets = nstats->flow_ctrl_octets; le32_to_cpu(xclient->broadcast_bytes_sent.lo);
estats->flow_ctrl_packet = nstats->flow_ctrl_packet;
estats->mng_discard = nstats->mng_discard; fstats->host_func_stats_start = ++fstats->host_func_stats_end;
estats->mng_octet_inp = nstats->mng_octet_inp;
estats->mng_octet_out = nstats->mng_octet_out;
estats->mng_packet_inp = nstats->mng_packet_inp;
estats->mng_packet_out = nstats->mng_packet_out;
estats->pbf_octets = nstats->pbf_octets;
estats->pbf_packet = nstats->pbf_packet;
estats->safc_inp = nstats->safc_inp;
xstats->done.hi = 0;
tstats->done.hi = 0;
nstats->done = 0;
return 0; return 0;
} }
static void bnx2x_update_net_stats(struct bnx2x *bp) static void bnx2x_net_stats_update(struct bnx2x *bp)
{ {
struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
struct bnx2x_eth_stats *estats = &bp->eth_stats;
struct net_device_stats *nstats = &bp->dev->stats; struct net_device_stats *nstats = &bp->dev->stats;
nstats->rx_packets = nstats->rx_packets =
...@@ -3000,28 +3278,35 @@ static void bnx2x_update_net_stats(struct bnx2x *bp) ...@@ -3000,28 +3278,35 @@ static void bnx2x_update_net_stats(struct bnx2x *bp)
bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) + bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi); bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi); nstats->rx_bytes = bnx2x_hilo(&estats->valid_bytes_received_hi);
nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
nstats->rx_dropped = estats->checksum_discard + estats->mac_discard; nstats->rx_dropped = old_tclient->checksum_discard +
estats->mac_discard;
nstats->tx_dropped = 0; nstats->tx_dropped = 0;
nstats->multicast = nstats->multicast =
bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi); bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
nstats->collisions = estats->single_collision_transmit_frames + nstats->collisions =
estats->multiple_collision_transmit_frames + estats->tx_stat_dot3statssinglecollisionframes_lo +
estats->late_collision_frames + estats->tx_stat_dot3statsmultiplecollisionframes_lo +
estats->excessive_collision_frames; estats->tx_stat_dot3statslatecollisions_lo +
estats->tx_stat_dot3statsexcessivecollisions_lo;
estats->jabber_packets_received =
old_tclient->packets_too_big_discard +
estats->rx_stat_dot3statsframestoolong_lo;
nstats->rx_length_errors = estats->runt_packets_received + nstats->rx_length_errors =
estats->jabber_packets_received; estats->rx_stat_etherstatsundersizepkts_lo +
nstats->rx_over_errors = estats->brb_discard + estats->jabber_packets_received;
nstats->rx_over_errors = estats->brb_drop_lo +
estats->brb_truncate_discard; estats->brb_truncate_discard;
nstats->rx_crc_errors = estats->crc_receive_errors; nstats->rx_crc_errors = estats->rx_stat_dot3statsfcserrors_lo;
nstats->rx_frame_errors = estats->alignment_errors; nstats->rx_frame_errors = estats->rx_stat_dot3statsalignmenterrors_lo;
nstats->rx_fifo_errors = estats->no_buff_discard; nstats->rx_fifo_errors = old_tclient->no_buff_discard;
nstats->rx_missed_errors = estats->xxoverflow_discard; nstats->rx_missed_errors = estats->xxoverflow_discard;
nstats->rx_errors = nstats->rx_length_errors + nstats->rx_errors = nstats->rx_length_errors +
...@@ -3031,39 +3316,48 @@ static void bnx2x_update_net_stats(struct bnx2x *bp) ...@@ -3031,39 +3316,48 @@ static void bnx2x_update_net_stats(struct bnx2x *bp)
nstats->rx_fifo_errors + nstats->rx_fifo_errors +
nstats->rx_missed_errors; nstats->rx_missed_errors;
nstats->tx_aborted_errors = estats->late_collision_frames + nstats->tx_aborted_errors =
estats->excessive_collision_frames; estats->tx_stat_dot3statslatecollisions_lo +
nstats->tx_carrier_errors = estats->false_carrier_detections; estats->tx_stat_dot3statsexcessivecollisions_lo;
nstats->tx_carrier_errors = estats->rx_stat_falsecarriererrors_lo;
nstats->tx_fifo_errors = 0; nstats->tx_fifo_errors = 0;
nstats->tx_heartbeat_errors = 0; nstats->tx_heartbeat_errors = 0;
nstats->tx_window_errors = 0; nstats->tx_window_errors = 0;
nstats->tx_errors = nstats->tx_aborted_errors + nstats->tx_errors = nstats->tx_aborted_errors +
nstats->tx_carrier_errors; nstats->tx_carrier_errors;
estats->mac_stx_start = ++estats->mac_stx_end;
} }
static void bnx2x_update_stats(struct bnx2x *bp) static void bnx2x_stats_update(struct bnx2x *bp)
{ {
if (!bnx2x_update_storm_stats(bp)) { u32 *stats_comp = bnx2x_sp(bp, stats_comp);
int update = 0;
if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { if (*stats_comp != DMAE_COMP_VAL)
bnx2x_update_bmac_stats(bp); return;
} else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) { if (bp->port.pmf)
bnx2x_update_emac_stats(bp); update = (bnx2x_hw_stats_update(bp) == 0);
} else { /* unreached */ update |= (bnx2x_storm_stats_update(bp) == 0);
BNX2X_ERR("no MAC active\n");
return; if (update)
} bnx2x_net_stats_update(bp);
bnx2x_update_net_stats(bp); else {
if (bp->stats_pending) {
bp->stats_pending++;
if (bp->stats_pending == 3) {
BNX2X_ERR("stats not updated for 3 times\n");
bnx2x_panic();
return;
}
}
} }
if (bp->msglevel & NETIF_MSG_TIMER) { if (bp->msglevel & NETIF_MSG_TIMER) {
struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
struct bnx2x_eth_stats *estats = &bp->eth_stats;
struct net_device_stats *nstats = &bp->dev->stats; struct net_device_stats *nstats = &bp->dev->stats;
int i; int i;
...@@ -3078,17 +3372,18 @@ static void bnx2x_update_stats(struct bnx2x *bp) ...@@ -3078,17 +3372,18 @@ static void bnx2x_update_stats(struct bnx2x *bp)
*bp->fp->rx_cons_sb, nstats->rx_packets); *bp->fp->rx_cons_sb, nstats->rx_packets);
printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n", printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n",
netif_queue_stopped(bp->dev)? "Xoff" : "Xon", netif_queue_stopped(bp->dev)? "Xoff" : "Xon",
estats->driver_xoff, estats->brb_discard); estats->driver_xoff, estats->brb_drop_lo);
printk(KERN_DEBUG "tstats: checksum_discard %u " printk(KERN_DEBUG "tstats: checksum_discard %u "
"packets_too_big_discard %u no_buff_discard %u " "packets_too_big_discard %u no_buff_discard %u "
"mac_discard %u mac_filter_discard %u " "mac_discard %u mac_filter_discard %u "
"xxovrflow_discard %u brb_truncate_discard %u " "xxovrflow_discard %u brb_truncate_discard %u "
"ttl0_discard %u\n", "ttl0_discard %u\n",
estats->checksum_discard, old_tclient->checksum_discard,
estats->packets_too_big_discard, old_tclient->packets_too_big_discard,
estats->no_buff_discard, estats->mac_discard, old_tclient->no_buff_discard, estats->mac_discard,
estats->mac_filter_discard, estats->xxoverflow_discard, estats->mac_filter_discard, estats->xxoverflow_discard,
estats->brb_truncate_discard, estats->ttl0_discard); estats->brb_truncate_discard,
old_tclient->ttl0_discard);
for_each_queue(bp, i) { for_each_queue(bp, i) {
printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i, printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i,
...@@ -3098,60 +3393,131 @@ static void bnx2x_update_stats(struct bnx2x *bp) ...@@ -3098,60 +3393,131 @@ static void bnx2x_update_stats(struct bnx2x *bp)
} }
} }
if (bp->state != BNX2X_STATE_OPEN) { bnx2x_hw_stats_post(bp);
DP(BNX2X_MSG_STATS, "state is %x, returning\n", bp->state); bnx2x_storm_stats_post(bp);
return; }
}
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
return;
#endif
/* loader */ static void bnx2x_port_stats_stop(struct bnx2x *bp)
if (bp->executer_idx) { {
struct dmae_command *dmae = &bp->dmae; struct dmae_command *dmae;
int port = BP_PORT(bp); u32 opcode;
int loader_idx = port * 8; int loader_idx = PMF_DMAE_C(bp);
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
memset(dmae, 0, sizeof(struct dmae_command)); bp->executer_idx = 0;
dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | DMAE_CMD_C_ENABLE |
DMAE_CMD_DST_RESET | DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
DMAE_CMD_ENDIANITY_B_DW_SWAP | DMAE_CMD_ENDIANITY_B_DW_SWAP |
#else #else
DMAE_CMD_ENDIANITY_DW_SWAP | DMAE_CMD_ENDIANITY_DW_SWAP |
#endif #endif
(port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0])); (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0]));
dmae->dst_addr_lo = (DMAE_REG_CMD_MEM + if (bp->port.port_stx) {
sizeof(struct dmae_command) *
(loader_idx + 1)) >> 2; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
if (bp->func_stx)
dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
else
dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
dmae->dst_addr_lo = bp->port.port_stx >> 2;
dmae->dst_addr_hi = 0; dmae->dst_addr_hi = 0;
dmae->len = sizeof(struct dmae_command) >> 2; dmae->len = sizeof(struct host_port_stats) >> 2;
dmae->len--; /* !!! for A0/1 only */ if (bp->func_stx) {
dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2; dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
dmae->comp_addr_hi = 0; dmae->comp_addr_hi = 0;
dmae->comp_val = 1; dmae->comp_val = 1;
} else {
dmae->comp_addr_lo =
U64_LO(bnx2x_sp_mapping(bp, stats_comp));
dmae->comp_addr_hi =
U64_HI(bnx2x_sp_mapping(bp, stats_comp));
dmae->comp_val = DMAE_COMP_VAL;
bnx2x_post_dmae(bp, dmae, loader_idx); *stats_comp = 0;
}
} }
if (bp->stats_state != STATS_STATE_ENABLE) { if (bp->func_stx) {
bp->stats_state = STATS_STATE_DISABLE;
return; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
dmae->dst_addr_lo = bp->func_stx >> 2;
dmae->dst_addr_hi = 0;
dmae->len = sizeof(struct host_func_stats) >> 2;
dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
dmae->comp_val = DMAE_COMP_VAL;
*stats_comp = 0;
} }
}
static void bnx2x_stats_stop(struct bnx2x *bp)
{
int update = 0;
bnx2x_stats_comp(bp);
if (bp->port.pmf)
update = (bnx2x_hw_stats_update(bp) == 0);
update |= (bnx2x_storm_stats_update(bp) == 0);
if (update) {
bnx2x_net_stats_update(bp);
if (bp->port.pmf)
bnx2x_port_stats_stop(bp);
if (bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, 0, 0, 0) == 0) { bnx2x_hw_stats_post(bp);
/* stats ramrod has it's own slot on the spe */ bnx2x_stats_comp(bp);
bp->spq_left++;
bp->stat_pending = 1;
} }
} }
static void bnx2x_stats_do_nothing(struct bnx2x *bp)
{
}
static const struct {
void (*action)(struct bnx2x *bp);
enum bnx2x_stats_state next_state;
} bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = {
/* state event */
{
/* DISABLED PMF */ {bnx2x_stats_pmf_update, STATS_STATE_DISABLED},
/* LINK_UP */ {bnx2x_stats_start, STATS_STATE_ENABLED},
/* UPDATE */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED},
/* STOP */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED}
},
{
/* ENABLED PMF */ {bnx2x_stats_pmf_start, STATS_STATE_ENABLED},
/* LINK_UP */ {bnx2x_stats_restart, STATS_STATE_ENABLED},
/* UPDATE */ {bnx2x_stats_update, STATS_STATE_ENABLED},
/* STOP */ {bnx2x_stats_stop, STATS_STATE_DISABLED}
}
};
static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
{
enum bnx2x_stats_state state = bp->stats_state;
bnx2x_stats_stm[state][event].action(bp);
bp->stats_state = bnx2x_stats_stm[state][event].next_state;
if ((event != STATS_EVENT_UPDATE) || (bp->msglevel & NETIF_MSG_TIMER))
DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
state, event, bp->stats_state);
}
static void bnx2x_timer(unsigned long data) static void bnx2x_timer(unsigned long data)
{ {
struct bnx2x *bp = (struct bnx2x *) data; struct bnx2x *bp = (struct bnx2x *) data;
...@@ -3194,10 +3560,9 @@ static void bnx2x_timer(unsigned long data) ...@@ -3194,10 +3560,9 @@ static void bnx2x_timer(unsigned long data)
} }
} }
if (bp->stats_state == STATS_STATE_DISABLE) if ((bp->state == BNX2X_STATE_OPEN) ||
goto timer_restart; (bp->state == BNX2X_STATE_DISABLED))
bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
bnx2x_update_stats(bp);
timer_restart: timer_restart:
mod_timer(&bp->timer, jiffies + bp->current_interval); mod_timer(&bp->timer, jiffies + bp->current_interval);
...@@ -3227,6 +3592,7 @@ static void bnx2x_init_sb(struct bnx2x *bp, int sb_id, ...@@ -3227,6 +3592,7 @@ static void bnx2x_init_sb(struct bnx2x *bp, int sb_id,
struct host_status_block *sb, dma_addr_t mapping) struct host_status_block *sb, dma_addr_t mapping)
{ {
int port = BP_PORT(bp); int port = BP_PORT(bp);
int func = BP_FUNC(bp);
int index; int index;
u64 section; u64 section;
...@@ -3240,6 +3606,8 @@ static void bnx2x_init_sb(struct bnx2x *bp, int sb_id, ...@@ -3240,6 +3606,8 @@ static void bnx2x_init_sb(struct bnx2x *bp, int sb_id,
REG_WR(bp, BAR_USTRORM_INTMEM + REG_WR(bp, BAR_USTRORM_INTMEM +
((USTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id)) + 4), ((USTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id)) + 4),
U64_HI(section)); U64_HI(section));
REG_WR8(bp, BAR_USTRORM_INTMEM + FP_USB_FUNC_OFF +
USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), func);
for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++) for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++)
REG_WR16(bp, BAR_USTRORM_INTMEM + REG_WR16(bp, BAR_USTRORM_INTMEM +
...@@ -3411,6 +3779,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, ...@@ -3411,6 +3779,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
REG_WR16(bp, BAR_XSTRORM_INTMEM + REG_WR16(bp, BAR_XSTRORM_INTMEM +
XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
bp->stats_pending = 0;
bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
} }
...@@ -3804,7 +4174,7 @@ static void bnx2x_nic_init(struct bnx2x *bp) ...@@ -3804,7 +4174,7 @@ static void bnx2x_nic_init(struct bnx2x *bp)
bnx2x_init_sp_ring(bp); bnx2x_init_sp_ring(bp);
bnx2x_init_context(bp); bnx2x_init_context(bp);
bnx2x_init_internal(bp); bnx2x_init_internal(bp);
bnx2x_init_stats(bp); bnx2x_storm_stats_init(bp);
bnx2x_init_ind_table(bp); bnx2x_init_ind_table(bp);
bnx2x_int_enable(bp); bnx2x_int_enable(bp);
} }
...@@ -5339,6 +5709,8 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) ...@@ -5339,6 +5709,8 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
} }
} }
bnx2x_stats_init(bp);
bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; bp->state = BNX2X_STATE_OPENING_WAIT4_PORT;
/* Enable Rx interrupt handling before sending the ramrod /* Enable Rx interrupt handling before sending the ramrod
...@@ -5595,6 +5967,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) ...@@ -5595,6 +5967,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
del_timer_sync(&bp->timer); del_timer_sync(&bp->timer);
SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb, SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
(DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
/* Wait until all fast path tasks complete */ /* Wait until all fast path tasks complete */
for_each_queue(bp, i) { for_each_queue(bp, i) {
...@@ -6641,7 +7014,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -6641,7 +7014,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
bp->port.advertising); bp->port.advertising);
if (netif_running(dev)) { if (netif_running(dev)) {
bnx2x_stop_stats(bp); bnx2x_stats_handle(bp, STATS_EVENT_STOP);
bnx2x_link_set(bp); bnx2x_link_set(bp);
} }
...@@ -6738,7 +7111,7 @@ static int bnx2x_nway_reset(struct net_device *dev) ...@@ -6738,7 +7111,7 @@ static int bnx2x_nway_reset(struct net_device *dev)
return 0; return 0;
if (netif_running(dev)) { if (netif_running(dev)) {
bnx2x_stop_stats(bp); bnx2x_stats_handle(bp, STATS_EVENT_STOP);
bnx2x_link_set(bp); bnx2x_link_set(bp);
} }
...@@ -7128,10 +7501,13 @@ static int bnx2x_set_eeprom(struct net_device *dev, ...@@ -7128,10 +7501,13 @@ static int bnx2x_set_eeprom(struct net_device *dev,
bp->link_params.ext_phy_config, bp->link_params.ext_phy_config,
(bp->state != BNX2X_STATE_CLOSED), (bp->state != BNX2X_STATE_CLOSED),
eebuf, eeprom->len); eebuf, eeprom->len);
if ((bp->state == BNX2X_STATE_OPEN) ||
(bp->state == BNX2X_STATE_DISABLED)) {
rc |= bnx2x_link_reset(&bp->link_params, rc |= bnx2x_link_reset(&bp->link_params,
&bp->link_vars); &bp->link_vars);
rc |= bnx2x_phy_init(&bp->link_params, rc |= bnx2x_phy_init(&bp->link_params,
&bp->link_vars); &bp->link_vars);
}
bnx2x_phy_hw_unlock(bp); bnx2x_phy_hw_unlock(bp);
} else /* Only the PMF can access the PHY */ } else /* Only the PMF can access the PHY */
...@@ -7274,7 +7650,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev, ...@@ -7274,7 +7650,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
"req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl); "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl);
if (netif_running(dev)) { if (netif_running(dev)) {
bnx2x_stop_stats(bp); bnx2x_stats_handle(bp, STATS_EVENT_STOP);
bnx2x_link_set(bp); bnx2x_link_set(bp);
} }
...@@ -7330,7 +7706,6 @@ static void bnx2x_self_test(struct net_device *dev, ...@@ -7330,7 +7706,6 @@ static void bnx2x_self_test(struct net_device *dev,
} }
stats_state = bp->stats_state; stats_state = bp->stats_state;
bnx2x_stop_stats(bp);
if (bnx2x_mc_assert(bp) != 0) { if (bnx2x_mc_assert(bp) != 0) {
buf[0] = 1; buf[0] = 1;
...@@ -7340,100 +7715,96 @@ static void bnx2x_self_test(struct net_device *dev, ...@@ -7340,100 +7715,96 @@ static void bnx2x_self_test(struct net_device *dev,
#ifdef BNX2X_EXTRA_DEBUG #ifdef BNX2X_EXTRA_DEBUG
bnx2x_panic_dump(bp); bnx2x_panic_dump(bp);
#endif #endif
bp->stats_state = stats_state;
} }
static struct { static const struct {
long offset;
int size;
u32 flags;
char string[ETH_GSTRING_LEN]; char string[ETH_GSTRING_LEN];
} bnx2x_stats_str_arr[BNX2X_NUM_STATS] = { } bnx2x_stats_arr[BNX2X_NUM_STATS] = {
{ "rx_bytes"}, /* 1 */ { STATS_OFFSET32(valid_bytes_received_hi), 8, 1, "rx_bytes" },
{ "rx_error_bytes"}, { STATS_OFFSET32(error_bytes_received_hi), 8, 1, "rx_error_bytes" },
{ "tx_bytes"}, { STATS_OFFSET32(total_bytes_transmitted_hi), 8, 1, "tx_bytes" },
{ "tx_error_bytes"}, { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi), 8, 0, "tx_error_bytes" },
{ "rx_ucast_packets"}, { STATS_OFFSET32(total_unicast_packets_received_hi),
{ "rx_mcast_packets"}, 8, 1, "rx_ucast_packets" },
{ "rx_bcast_packets"}, { STATS_OFFSET32(total_multicast_packets_received_hi),
{ "tx_ucast_packets"}, 8, 1, "rx_mcast_packets" },
{ "tx_mcast_packets"}, { STATS_OFFSET32(total_broadcast_packets_received_hi),
{ "tx_bcast_packets"}, 8, 1, "rx_bcast_packets" },
{ "tx_mac_errors"}, /* 10 */ { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
{ "tx_carrier_errors"}, 8, 1, "tx_packets" },
{ "rx_crc_errors"}, { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
{ "rx_align_errors"}, 8, 0, "tx_mac_errors" },
{ "tx_single_collisions"}, /* 10 */{ STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
{ "tx_multi_collisions"}, 8, 0, "tx_carrier_errors" },
{ "tx_deferred"}, { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
{ "tx_excess_collisions"}, 8, 0, "rx_crc_errors" },
{ "tx_late_collisions"}, { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
{ "tx_total_collisions"}, 8, 0, "rx_align_errors" },
{ "rx_fragments"}, /* 20 */ { STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
{ "rx_jabbers"}, 8, 0, "tx_single_collisions" },
{ "rx_undersize_packets"}, { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
{ "rx_oversize_packets"}, 8, 0, "tx_multi_collisions" },
{ "rx_xon_frames"}, { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
{ "rx_xoff_frames"}, 8, 0, "tx_deferred" },
{ "tx_xon_frames"}, { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
{ "tx_xoff_frames"}, 8, 0, "tx_excess_collisions" },
{ "rx_mac_ctrl_frames"}, { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi),
{ "rx_filtered_packets"}, 8, 0, "tx_late_collisions" },
{ "rx_discards"}, /* 30 */ { STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
{ "brb_discard"}, 8, 0, "tx_total_collisions" },
{ "brb_truncate"}, { STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
{ "xxoverflow"} 8, 0, "rx_fragments" },
}; /* 20 */{ STATS_OFFSET32(rx_stat_etherstatsjabbers_hi), 8, 0, "rx_jabbers" },
{ STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
#define STATS_OFFSET32(offset_name) \ 8, 0, "rx_undersize_packets" },
(offsetof(struct bnx2x_eth_stats, offset_name) / 4) { STATS_OFFSET32(jabber_packets_received),
4, 1, "rx_oversize_packets" },
static unsigned long bnx2x_stats_offset_arr[BNX2X_NUM_STATS] = { { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
STATS_OFFSET32(total_bytes_received_hi), 8, 0, "tx_64_byte_packets" },
STATS_OFFSET32(stat_IfHCInBadOctets_hi), { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
STATS_OFFSET32(total_bytes_transmitted_hi), 8, 0, "tx_65_to_127_byte_packets" },
STATS_OFFSET32(stat_IfHCOutBadOctets_hi), { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi),
STATS_OFFSET32(total_unicast_packets_received_hi), 8, 0, "tx_128_to_255_byte_packets" },
STATS_OFFSET32(total_multicast_packets_received_hi), { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi),
STATS_OFFSET32(total_broadcast_packets_received_hi), 8, 0, "tx_256_to_511_byte_packets" },
STATS_OFFSET32(total_unicast_packets_transmitted_hi), { STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi),
STATS_OFFSET32(total_multicast_packets_transmitted_hi), 8, 0, "tx_512_to_1023_byte_packets" },
STATS_OFFSET32(total_broadcast_packets_transmitted_hi), { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */ 8, 0, "tx_1024_to_1522_byte_packets" },
STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors), { STATS_OFFSET32(etherstatspktsover1522octets_hi),
STATS_OFFSET32(crc_receive_errors), 8, 0, "tx_1523_to_9022_byte_packets" },
STATS_OFFSET32(alignment_errors), /* 30 */{ STATS_OFFSET32(rx_stat_xonpauseframesreceived_hi),
STATS_OFFSET32(single_collision_transmit_frames), 8, 0, "rx_xon_frames" },
STATS_OFFSET32(multiple_collision_transmit_frames), { STATS_OFFSET32(rx_stat_xoffpauseframesreceived_hi),
STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions), 8, 0, "rx_xoff_frames" },
STATS_OFFSET32(excessive_collision_frames), { STATS_OFFSET32(tx_stat_outxonsent_hi), 8, 0, "tx_xon_frames" },
STATS_OFFSET32(late_collision_frames), { STATS_OFFSET32(tx_stat_outxoffsent_hi), 8, 0, "tx_xoff_frames" },
STATS_OFFSET32(number_of_bugs_found_in_stats_spec), { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
STATS_OFFSET32(runt_packets_received), /* 20 */ 8, 0, "rx_mac_ctrl_frames" },
STATS_OFFSET32(jabber_packets_received), { STATS_OFFSET32(mac_filter_discard), 4, 1, "rx_filtered_packets" },
STATS_OFFSET32(error_runt_packets_received), { STATS_OFFSET32(no_buff_discard), 4, 1, "rx_discards" },
STATS_OFFSET32(error_jabber_packets_received), { STATS_OFFSET32(xxoverflow_discard), 4, 1, "rx_fw_discards" },
STATS_OFFSET32(pause_xon_frames_received), { STATS_OFFSET32(brb_drop_hi), 8, 1, "brb_discard" },
STATS_OFFSET32(pause_xoff_frames_received), /* 39 */{ STATS_OFFSET32(brb_truncate_discard), 8, 1, "brb_truncate" }
STATS_OFFSET32(pause_xon_frames_transmitted),
STATS_OFFSET32(pause_xoff_frames_transmitted),
STATS_OFFSET32(control_frames_received),
STATS_OFFSET32(mac_filter_discard),
STATS_OFFSET32(no_buff_discard), /* 30 */
STATS_OFFSET32(brb_discard),
STATS_OFFSET32(brb_truncate_discard),
STATS_OFFSET32(xxoverflow_discard)
};
static u8 bnx2x_stats_len_arr[BNX2X_NUM_STATS] = {
8, 0, 8, 0, 8, 8, 8, 8, 8, 8,
4, 0, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4
}; };
static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
{ {
struct bnx2x *bp = netdev_priv(dev);
int i, j;
switch (stringset) { switch (stringset) {
case ETH_SS_STATS: case ETH_SS_STATS:
memcpy(buf, bnx2x_stats_str_arr, sizeof(bnx2x_stats_str_arr)); for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags))
continue;
strcpy(buf + j*ETH_GSTRING_LEN,
bnx2x_stats_arr[i].string);
j++;
}
break; break;
case ETH_SS_TEST: case ETH_SS_TEST:
...@@ -7444,34 +7815,44 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) ...@@ -7444,34 +7815,44 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
static int bnx2x_get_stats_count(struct net_device *dev) static int bnx2x_get_stats_count(struct net_device *dev)
{ {
return BNX2X_NUM_STATS; struct bnx2x *bp = netdev_priv(dev);
int i, num_stats = 0;
for (i = 0; i < BNX2X_NUM_STATS; i++) {
if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags))
continue;
num_stats++;
}
return num_stats;
} }
static void bnx2x_get_ethtool_stats(struct net_device *dev, static void bnx2x_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *buf) struct ethtool_stats *stats, u64 *buf)
{ {
struct bnx2x *bp = netdev_priv(dev); struct bnx2x *bp = netdev_priv(dev);
u32 *hw_stats = (u32 *)bnx2x_sp_check(bp, eth_stats); u32 *hw_stats = (u32 *)&bp->eth_stats;
int i; int i, j;
for (i = 0; i < BNX2X_NUM_STATS; i++) { for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
if (bnx2x_stats_len_arr[i] == 0) { if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags))
/* skip this counter */
buf[i] = 0;
continue; continue;
}
if (!hw_stats) { if (bnx2x_stats_arr[i].size == 0) {
buf[i] = 0; /* skip this counter */
buf[j] = 0;
j++;
continue; continue;
} }
if (bnx2x_stats_len_arr[i] == 4) { if (bnx2x_stats_arr[i].size == 4) {
/* 4-byte counter */ /* 4-byte counter */
buf[i] = (u64) *(hw_stats + bnx2x_stats_offset_arr[i]); buf[j] = (u64) *(hw_stats + bnx2x_stats_arr[i].offset);
j++;
continue; continue;
} }
/* 8-byte counter */ /* 8-byte counter */
buf[i] = HILO_U64(*(hw_stats + bnx2x_stats_offset_arr[i]), buf[j] = HILO_U64(*(hw_stats + bnx2x_stats_arr[i].offset),
*(hw_stats + bnx2x_stats_offset_arr[i] + 1)); *(hw_stats + bnx2x_stats_arr[i].offset + 1));
j++;
} }
} }
...@@ -7546,7 +7927,7 @@ static struct ethtool_ops bnx2x_ethtool_ops = { ...@@ -7546,7 +7927,7 @@ static struct ethtool_ops bnx2x_ethtool_ops = {
.get_strings = bnx2x_get_strings, .get_strings = bnx2x_get_strings,
.phys_id = bnx2x_phys_id, .phys_id = bnx2x_phys_id,
.get_stats_count = bnx2x_get_stats_count, .get_stats_count = bnx2x_get_stats_count,
.get_ethtool_stats = bnx2x_get_ethtool_stats .get_ethtool_stats = bnx2x_get_ethtool_stats,
}; };
/* end of ethtool_ops */ /* end of ethtool_ops */
...@@ -7665,7 +8046,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -7665,7 +8046,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
fp = &bp->fp[fp_index]; fp = &bp->fp[fp_index];
if (unlikely(bnx2x_tx_avail(bp->fp) < if (unlikely(bnx2x_tx_avail(bp->fp) <
(skb_shinfo(skb)->nr_frags + 3))) { (skb_shinfo(skb)->nr_frags + 3))) {
bp->slowpath->eth_stats.driver_xoff++, bp->eth_stats.driver_xoff++,
netif_stop_queue(dev); netif_stop_queue(dev);
BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
...@@ -7897,7 +8278,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -7897,7 +8278,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
netif_stop_queue(dev); netif_stop_queue(dev);
bp->slowpath->eth_stats.driver_xoff++; bp->eth_stats.driver_xoff++;
if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3) if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
netif_wake_queue(dev); netif_wake_queue(dev);
} }
...@@ -7906,26 +8287,26 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -7906,26 +8287,26 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
/* Called with rtnl_lock */ /* called with rtnl_lock */
static int bnx2x_open(struct net_device *dev) static int bnx2x_open(struct net_device *dev)
{ {
struct bnx2x *bp = netdev_priv(dev); struct bnx2x *bp = netdev_priv(dev);
bnx2x_set_power_state(bp, PCI_D0); bnx2x_set_power_state(bp, PCI_D0);
return bnx2x_nic_load(bp, 1); return bnx2x_nic_load(bp, LOAD_OPEN);
} }
/* Called with rtnl_lock */ /* called with rtnl_lock */
static int bnx2x_close(struct net_device *dev) static int bnx2x_close(struct net_device *dev)
{ {
struct bnx2x *bp = netdev_priv(dev); struct bnx2x *bp = netdev_priv(dev);
/* Unload the driver, release IRQs */ /* Unload the driver, release IRQs */
bnx2x_nic_unload(bp, 1); bnx2x_nic_unload(bp, UNLOAD_CLOSE);
if (atomic_read(&bp->pdev->enable_cnt) == 1)
if (!CHIP_REV_IS_SLOW(bp)) if (!CHIP_REV_IS_SLOW(bp))
bnx2x_set_power_state(bp, PCI_D3hot); bnx2x_set_power_state(bp, PCI_D3hot);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment