diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/benet/be.h | 38 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.c | 161 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 414 | ||||
-rw-r--r-- | drivers/net/benet/be_ethtool.c | 108 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 386 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.c | 16 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 3 |
7 files changed, 975 insertions, 151 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 41bbc32123f..0b73dcf2692 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -244,6 +244,43 @@ struct be_rx_obj { struct be_drv_stats { u8 be_on_die_temperature; + u64 be_tx_events; + u64 eth_red_drops; + u64 rx_drops_no_pbuf; + u64 rx_drops_no_txpb; + u64 rx_drops_no_erx_descr; + u64 rx_drops_no_tpre_descr; + u64 rx_drops_too_many_frags; + u64 rx_drops_invalid_ring; + u64 forwarded_packets; + u64 rx_drops_mtu; + u64 rx_crc_errors; + u64 rx_alignment_symbol_errors; + u64 rx_pause_frames; + u64 rx_priority_pause_frames; + u64 rx_control_frames; + u64 rx_in_range_errors; + u64 rx_out_range_errors; + u64 rx_frame_too_long; + u64 rx_address_match_errors; + u64 rx_dropped_too_small; + u64 rx_dropped_too_short; + u64 rx_dropped_header_too_small; + u64 rx_dropped_tcp_length; + u64 rx_dropped_runt; + u64 rx_ip_checksum_errs; + u64 rx_tcp_checksum_errs; + u64 rx_udp_checksum_errs; + u64 rx_switched_unicast_packets; + u64 rx_switched_multicast_packets; + u64 rx_switched_broadcast_packets; + u64 tx_pauseframes; + u64 tx_priority_pauseframes; + u64 tx_controlframes; + u64 rxpp_fifo_overflow_drop; + u64 rx_input_fifo_overflow_drop; + u64 pmem_fifo_overflow_drop; + u64 jabber_events; }; struct be_vf_cfg { @@ -483,5 +520,6 @@ extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped); extern void be_link_status_update(struct be_adapter *adapter, bool link_up); extern void netdev_stats_update(struct be_adapter *adapter); +extern void be_parse_stats(struct be_adapter *adapter); extern int be_load_fw(struct be_adapter *adapter, u8 *func); #endif /* BE_H */ diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index f2c90997fab..2463b1c9792 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -71,19 +71,38 @@ static int be_mcc_compl_process(struct be_adapter *adapter, compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & CQE_STATUS_COMPL_MASK; - if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) && + if (((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) || + (compl->tag0 == OPCODE_COMMON_WRITE_OBJECT)) && (compl->tag1 == CMD_SUBSYSTEM_COMMON)) { adapter->flash_status = compl_status; complete(&adapter->flash_compl); } if (compl_status == MCC_STATUS_SUCCESS) { - if ((compl->tag0 == OPCODE_ETH_GET_STATISTICS) && + if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) || + (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) && (compl->tag1 == CMD_SUBSYSTEM_ETH)) { - struct be_cmd_resp_get_stats *resp = - adapter->stats_cmd.va; - be_dws_le_to_cpu(&resp->hw_stats, - sizeof(resp->hw_stats)); + if (adapter->generation == BE_GEN3) { + if (lancer_chip(adapter)) { + struct lancer_cmd_resp_pport_stats + *resp = adapter->stats_cmd.va; + be_dws_le_to_cpu(&resp->pport_stats, + sizeof(resp->pport_stats)); + } else { + struct be_cmd_resp_get_stats_v1 *resp = + adapter->stats_cmd.va; + + be_dws_le_to_cpu(&resp->hw_stats, + sizeof(resp->hw_stats)); + } + } else { + struct be_cmd_resp_get_stats_v0 *resp = + adapter->stats_cmd.va; + + be_dws_le_to_cpu(&resp->hw_stats, + sizeof(resp->hw_stats)); + } + be_parse_stats(adapter); netdev_stats_update(adapter); adapter->stats_cmd_sent = false; } @@ -1075,7 +1094,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain) int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) { struct be_mcc_wrb *wrb; - struct be_cmd_req_get_stats *req; + struct be_cmd_req_hdr *hdr; struct be_sge *sge; int status = 0; @@ -1089,14 +1108,61 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) status = -EBUSY; goto err; } - req = nonemb_cmd->va; + hdr = nonemb_cmd->va; sge = nonembedded_sgl(wrb); - be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1, + be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1, OPCODE_ETH_GET_STATISTICS); + be_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH, + OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size); + + if (adapter->generation == BE_GEN3) + hdr->version = 1; + + wrb->tag1 = CMD_SUBSYSTEM_ETH; + sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); + sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); + sge->len = cpu_to_le32(nonemb_cmd->size); + + be_mcc_notify(adapter); + adapter->stats_cmd_sent = true; + +err: + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + +/* Lancer Stats */ +int lancer_cmd_get_pport_stats(struct be_adapter *adapter, + struct be_dma_mem *nonemb_cmd) +{ + + struct be_mcc_wrb *wrb; + struct lancer_cmd_req_pport_stats *req; + struct be_sge *sge; + int status = 0; + + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } + req = nonemb_cmd->va; + sge = nonembedded_sgl(wrb); + + be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1, + OPCODE_ETH_GET_PPORT_STATS); + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, - OPCODE_ETH_GET_STATISTICS, sizeof(*req)); + OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size); + + + req->cmd_params.params.pport_num = cpu_to_le16(adapter->port_num); + req->cmd_params.params.reset_stats = 0; + wrb->tag1 = CMD_SUBSYSTEM_ETH; sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); @@ -1736,6 +1802,81 @@ err: return status; } +int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, + u32 data_size, u32 data_offset, const char *obj_name, + u32 *data_written, u8 *addn_status) +{ + struct be_mcc_wrb *wrb; + struct lancer_cmd_req_write_object *req; + struct lancer_cmd_resp_write_object *resp; + void *ctxt = NULL; + int status; + + spin_lock_bh(&adapter->mcc_lock); + adapter->flash_status = 0; + + wrb = wrb_from_mccq(adapter); + if (!wrb) { + status = -EBUSY; + goto err_unlock; + } + + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(struct lancer_cmd_req_write_object), + true, 1, OPCODE_COMMON_WRITE_OBJECT); + wrb->tag1 = CMD_SUBSYSTEM_COMMON; + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_WRITE_OBJECT, + sizeof(struct lancer_cmd_req_write_object)); + + ctxt = &req->context; + AMAP_SET_BITS(struct amap_lancer_write_obj_context, + write_length, ctxt, data_size); + + if (data_size == 0) + AMAP_SET_BITS(struct amap_lancer_write_obj_context, + eof, ctxt, 1); + else + AMAP_SET_BITS(struct amap_lancer_write_obj_context, + eof, ctxt, 0); + + be_dws_cpu_to_le(ctxt, sizeof(req->context)); + req->write_offset = cpu_to_le32(data_offset); + strcpy(req->object_name, obj_name); + req->descriptor_count = cpu_to_le32(1); + req->buf_len = cpu_to_le32(data_size); + req->addr_low = cpu_to_le32((cmd->dma + + sizeof(struct lancer_cmd_req_write_object)) + & 0xFFFFFFFF); + req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma + + sizeof(struct lancer_cmd_req_write_object))); + + be_mcc_notify(adapter); + spin_unlock_bh(&adapter->mcc_lock); + + if (!wait_for_completion_timeout(&adapter->flash_compl, + msecs_to_jiffies(12000))) + status = -1; + else + status = adapter->flash_status; + + resp = embedded_payload(wrb); + if (!status) { + *data_written = le32_to_cpu(resp->actual_write_len); + } else { + *addn_status = resp->additional_status; + status = resp->status; + } + + return status; + +err_unlock: + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, u32 flash_type, u32 flash_opcode, u32 buf_size) { diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 78256b65cb0..8148cc66cbe 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -193,6 +193,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_GET_PHY_DETAILS 102 #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 +#define OPCODE_COMMON_WRITE_OBJECT 172 #define OPCODE_ETH_RSS_CONFIG 1 #define OPCODE_ETH_ACPI_CONFIG 2 @@ -203,6 +204,7 @@ struct be_mcc_mailbox { #define OPCODE_ETH_TX_DESTROY 9 #define OPCODE_ETH_RX_DESTROY 10 #define OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG 12 +#define OPCODE_ETH_GET_PPORT_STATS 18 #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 @@ -568,7 +570,7 @@ struct be_cmd_req_if_destroy { }; /*************** HW Stats Get **********************************/ -struct be_port_rxf_stats { +struct be_port_rxf_stats_v0 { u32 rx_bytes_lsd; /* dword 0*/ u32 rx_bytes_msd; /* dword 1*/ u32 rx_total_frames; /* dword 2*/ @@ -637,8 +639,8 @@ struct be_port_rxf_stats { u32 rx_input_fifo_overflow; /* dword 65*/ }; -struct be_rxf_stats { - struct be_port_rxf_stats port[2]; +struct be_rxf_stats_v0 { + struct be_port_rxf_stats_v0 port[2]; u32 rx_drops_no_pbuf; /* dword 132*/ u32 rx_drops_no_txpb; /* dword 133*/ u32 rx_drops_no_erx_descr; /* dword 134*/ @@ -661,36 +663,227 @@ struct be_rxf_stats { u32 rsvd1[6]; }; -struct be_erx_stats { +struct be_erx_stats_v0 { u32 rx_drops_no_fragments[44]; /* dwordS 0 to 43*/ - u32 debug_wdma_sent_hold; /* dword 44*/ - u32 debug_wdma_pbfree_sent_hold; /* dword 45*/ - u32 debug_wdma_zerobyte_pbfree_sent_hold; /* dword 46*/ - u32 debug_pmem_pbuf_dealloc; /* dword 47*/ + u32 rsvd[4]; }; struct be_pmem_stats { u32 eth_red_drops; - u32 rsvd[4]; + u32 rsvd[5]; }; -struct be_hw_stats { - struct be_rxf_stats rxf; +struct be_hw_stats_v0 { + struct be_rxf_stats_v0 rxf; u32 rsvd[48]; - struct be_erx_stats erx; + struct be_erx_stats_v0 erx; struct be_pmem_stats pmem; }; -struct be_cmd_req_get_stats { +struct be_cmd_req_get_stats_v0 { + struct be_cmd_req_hdr hdr; + u8 rsvd[sizeof(struct be_hw_stats_v0)]; +}; + +struct be_cmd_resp_get_stats_v0 { + struct be_cmd_resp_hdr hdr; + struct be_hw_stats_v0 hw_stats; +}; + +#define make_64bit_val(hi_32, lo_32) (((u64)hi_32<<32) | lo_32) +struct lancer_cmd_pport_stats { + u32 tx_packets_lo; + u32 tx_packets_hi; + u32 tx_unicast_packets_lo; + u32 tx_unicast_packets_hi; + u32 tx_multicast_packets_lo; + u32 tx_multicast_packets_hi; + u32 tx_broadcast_packets_lo; + u32 tx_broadcast_packets_hi; + u32 tx_bytes_lo; + u32 tx_bytes_hi; + u32 tx_unicast_bytes_lo; + u32 tx_unicast_bytes_hi; + u32 tx_multicast_bytes_lo; + u32 tx_multicast_bytes_hi; + u32 tx_broadcast_bytes_lo; + u32 tx_broadcast_bytes_hi; + u32 tx_discards_lo; + u32 tx_discards_hi; + u32 tx_errors_lo; + u32 tx_errors_hi; + u32 tx_pause_frames_lo; + u32 tx_pause_frames_hi; + u32 tx_pause_on_frames_lo; + u32 tx_pause_on_frames_hi; + u32 tx_pause_off_frames_lo; + u32 tx_pause_off_frames_hi; + u32 tx_internal_mac_errors_lo; + u32 tx_internal_mac_errors_hi; + u32 tx_control_frames_lo; + u32 tx_control_frames_hi; + u32 tx_packets_64_bytes_lo; + u32 tx_packets_64_bytes_hi; + u32 tx_packets_65_to_127_bytes_lo; + u32 tx_packets_65_to_127_bytes_hi; + u32 tx_packets_128_to_255_bytes_lo; + u32 tx_packets_128_to_255_bytes_hi; + u32 tx_packets_256_to_511_bytes_lo; + u32 tx_packets_256_to_511_bytes_hi; + u32 tx_packets_512_to_1023_bytes_lo; + u32 tx_packets_512_to_1023_bytes_hi; + u32 tx_packets_1024_to_1518_bytes_lo; + u32 tx_packets_1024_to_1518_bytes_hi; + u32 tx_packets_1519_to_2047_bytes_lo; + u32 tx_packets_1519_to_2047_bytes_hi; + u32 tx_packets_2048_to_4095_bytes_lo; + u32 tx_packets_2048_to_4095_bytes_hi; + u32 tx_packets_4096_to_8191_bytes_lo; + u32 tx_packets_4096_to_8191_bytes_hi; + u32 tx_packets_8192_to_9216_bytes_lo; + u32 tx_packets_8192_to_9216_bytes_hi; + u32 tx_lso_packets_lo; + u32 tx_lso_packets_hi; + u32 rx_packets_lo; + u32 rx_packets_hi; + u32 rx_unicast_packets_lo; + u32 rx_unicast_packets_hi; + u32 rx_multicast_packets_lo; + u32 rx_multicast_packets_hi; + u32 rx_broadcast_packets_lo; + u32 rx_broadcast_packets_hi; + u32 rx_bytes_lo; + u32 rx_bytes_hi; + u32 rx_unicast_bytes_lo; + u32 rx_unicast_bytes_hi; + u32 rx_multicast_bytes_lo; + u32 rx_multicast_bytes_hi; + u32 rx_broadcast_bytes_lo; + u32 rx_broadcast_bytes_hi; + u32 rx_unknown_protos; + u32 rsvd_69; /* Word 69 is reserved */ + u32 rx_discards_lo; + u32 rx_discards_hi; + u32 rx_errors_lo; + u32 rx_errors_hi; + u32 rx_crc_errors_lo; + u32 rx_crc_errors_hi; + u32 rx_alignment_errors_lo; + u32 rx_alignment_errors_hi; + u32 rx_symbol_errors_lo; + u32 rx_symbol_errors_hi; + u32 rx_pause_frames_lo; + u32 rx_pause_frames_hi; + u32 rx_pause_on_frames_lo; + u32 rx_pause_on_frames_hi; + u32 rx_pause_off_frames_lo; + u32 rx_pause_off_frames_hi; + u32 rx_frames_too_long_lo; + u32 rx_frames_too_long_hi; + u32 rx_internal_mac_errors_lo; + u32 rx_internal_mac_errors_hi; + u32 rx_undersize_packets; + u32 rx_oversize_packets; + u32 rx_fragment_packets; + u32 rx_jabbers; + u32 rx_control_frames_lo; + u32 rx_control_frames_hi; + u32 rx_control_frames_unknown_opcode_lo; + u32 rx_control_frames_unknown_opcode_hi; + u32 rx_in_range_errors; + u32 rx_out_of_range_errors; + u32 rx_address_match_errors; + u32 rx_vlan_mismatch_errors; + u32 rx_dropped_too_small; + u32 rx_dropped_too_short; + u32 rx_dropped_header_too_small; + u32 rx_dropped_invalid_tcp_length; + u32 rx_dropped_runt; + u32 rx_ip_checksum_errors; + u32 rx_tcp_checksum_errors; + u32 rx_udp_checksum_errors; + u32 rx_non_rss_packets; + u32 rsvd_111; + u32 rx_ipv4_packets_lo; + u32 rx_ipv4_packets_hi; + u32 rx_ipv6_packets_lo; + u32 rx_ipv6_packets_hi; + u32 rx_ipv4_bytes_lo; + u32 rx_ipv4_bytes_hi; + u32 rx_ipv6_bytes_lo; + u32 rx_ipv6_bytes_hi; + u32 rx_nic_packets_lo; + u32 rx_nic_packets_hi; + u32 rx_tcp_packets_lo; + u32 rx_tcp_packets_hi; + u32 rx_iscsi_packets_lo; + u32 rx_iscsi_packets_hi; + u32 rx_management_packets_lo; + u32 rx_management_packets_hi; + u32 rx_switched_unicast_packets_lo; + u32 rx_switched_unicast_packets_hi; + u32 rx_switched_multicast_packets_lo; + u32 rx_switched_multicast_packets_hi; + u32 rx_switched_broadcast_packets_lo; + u32 rx_switched_broadcast_packets_hi; + u32 num_forwards_lo; + u32 num_forwards_hi; + u32 rx_fifo_overflow; + u32 rx_input_fifo_overflow; + u32 rx_drops_too_many_frags_lo; + u32 rx_drops_too_many_frags_hi; + u32 rx_drops_invalid_queue; + u32 rsvd_141; + u32 rx_drops_mtu_lo; + u32 rx_drops_mtu_hi; + u32 rx_packets_64_bytes_lo; + u32 rx_packets_64_bytes_hi; + u32 rx_packets_65_to_127_bytes_lo; + u32 rx_packets_65_to_127_bytes_hi; + u32 rx_packets_128_to_255_bytes_lo; + u32 rx_packets_128_to_255_bytes_hi; + u32 rx_packets_256_to_511_bytes_lo; + u32 rx_packets_256_to_511_bytes_hi; + u32 rx_packets_512_to_1023_bytes_lo; + u32 rx_packets_512_to_1023_bytes_hi; + u32 rx_packets_1024_to_1518_bytes_lo; + u32 rx_packets_1024_to_1518_bytes_hi; + u32 rx_packets_1519_to_2047_bytes_lo; + u32 rx_packets_1519_to_2047_bytes_hi; + u32 rx_packets_2048_to_4095_bytes_lo; + u32 rx_packets_2048_to_4095_bytes_hi; + u32 rx_packets_4096_to_8191_bytes_lo; + u32 rx_packets_4096_to_8191_bytes_hi; + u32 rx_packets_8192_to_9216_bytes_lo; + u32 rx_packets_8192_to_9216_bytes_hi; +}; + +struct pport_stats_params { + u16 pport_num; + u8 rsvd; + u8 reset_stats; +}; + +struct lancer_cmd_req_pport_stats { struct be_cmd_req_hdr hdr; - u8 rsvd[sizeof(struct be_hw_stats)]; + union { + struct pport_stats_params params; + u8 rsvd[sizeof(struct lancer_cmd_pport_stats)]; + } cmd_params; }; -struct be_cmd_resp_get_stats { +struct lancer_cmd_resp_pport_stats { struct be_cmd_resp_hdr hdr; - struct be_hw_stats hw_stats; + struct lancer_cmd_pport_stats pport_stats; }; +static inline struct lancer_cmd_pport_stats* + pport_stats_from_cmd(struct be_adapter *adapter) +{ + struct lancer_cmd_resp_pport_stats *cmd = adapter->stats_cmd.va; + return &cmd->pport_stats; +} + struct be_cmd_req_get_cntl_addnl_attribs { struct be_cmd_req_hdr hdr; u8 rsvd[8]; @@ -728,13 +921,6 @@ struct be_cmd_req_mcast_mac_config { struct macaddr mac[BE_MAX_MC]; } __packed; -static inline struct be_hw_stats * -hw_stats_from_cmd(struct be_cmd_resp_get_stats *cmd) -{ - return &cmd->hw_stats; -} - - /******************* RX FILTER ******************************/ struct be_cmd_req_rx_filter { struct be_cmd_req_hdr hdr; @@ -946,6 +1132,36 @@ struct be_cmd_write_flashrom { struct flashrom_params params; }; +/**************** Lancer Firmware Flash ************/ +struct amap_lancer_write_obj_context { + u8 write_length[24]; + u8 reserved1[7]; + u8 eof; +} __packed; + +struct lancer_cmd_req_write_object { + struct be_cmd_req_hdr hdr; + u8 context[sizeof(struct amap_lancer_write_obj_context) / 8]; + u32 write_offset; + u8 object_name[104]; + u32 descriptor_count; + u32 buf_len; + u32 addr_low; + u32 addr_high; +}; + +struct lancer_cmd_resp_write_object { + u8 opcode; + u8 subsystem; + u8 rsvd1[2]; + u8 status; + u8 additional_status; + u8 rsvd2[2]; + u32 resp_len; + u32 actual_resp_len; + u32 actual_write_len; +}; + /************************ WOL *******************************/ struct be_cmd_req_acpi_wol_magic_config{ struct be_cmd_req_hdr hdr; @@ -1087,6 +1303,151 @@ struct be_cmd_resp_set_func_cap { u8 rsvd[212]; }; +/*************** HW Stats Get v1 **********************************/ +#define BE_TXP_SW_SZ 48 +struct be_port_rxf_stats_v1 { + u32 rsvd0[12]; + u32 rx_crc_errors; + u32 rx_alignment_symbol_errors; + u32 rx_pause_frames; + u32 rx_priority_pause_frames; + u32 rx_control_frames; + u32 rx_in_range_errors; + u32 rx_out_range_errors; + u32 rx_frame_too_long; + u32 rx_address_match_errors; + u32 rx_dropped_too_small; + u32 rx_dropped_too_short; + u32 rx_dropped_header_too_small; + u32 rx_dropped_tcp_length; + u32 rx_dropped_runt; + u32 rsvd1[10]; + u32 rx_ip_checksum_errs; + u32 rx_tcp_checksum_errs; + u32 rx_udp_checksum_errs; + u32 rsvd2[7]; + u32 rx_switched_unicast_packets; + u32 rx_switched_multicast_packets; + u32 rx_switched_broadcast_packets; + u32 rsvd3[3]; + u32 tx_pauseframes; + u32 tx_priority_pauseframes; + u32 tx_controlframes; + u32 rsvd4[10]; + u32 rxpp_fifo_overflow_drop; + u32 rx_input_fifo_overflow_drop; + u32 pmem_fifo_overflow_drop; + u32 jabber_events; + u32 rsvd5[3]; +}; + + +struct be_rxf_stats_v1 { + struct be_port_rxf_stats_v1 port[4]; + u32 rsvd0[2]; + u32 rx_drops_no_pbuf; + u32 rx_drops_no_txpb; + u32 rx_drops_no_erx_descr; + u32 rx_drops_no_tpre_descr; + u32 rsvd1[6]; + u32 rx_drops_too_many_frags; + u32 rx_drops_invalid_ring; + u32 forwarded_packets; + u32 rx_drops_mtu; + u32 rsvd2[14]; +}; + +struct be_erx_stats_v1 { + u32 rx_drops_no_fragments[68]; /* dwordS 0 to 67*/ + u32 rsvd[4]; +}; + +struct be_hw_stats_v1 { + struct be_rxf_stats_v1 rxf; + u32 rsvd0[BE_TXP_SW_SZ]; + struct be_erx_stats_v1 erx; + struct be_pmem_stats pmem; + u32 rsvd1[3]; +}; + +struct be_cmd_req_get_stats_v1 { + struct be_cmd_req_hdr hdr; + u8 rsvd[sizeof(struct be_hw_stats_v1)]; +}; + +struct be_cmd_resp_get_stats_v1 { + struct be_cmd_resp_hdr hdr; + struct be_hw_stats_v1 hw_stats; +}; + +static inline void * +hw_stats_from_cmd(struct be_adapter *adapter) +{ + if (adapter->generation == BE_GEN3) { + struct be_cmd_resp_get_stats_v1 *cmd = adapter->stats_cmd.va; + + return &cmd->hw_stats; + } else { + struct be_cmd_resp_get_stats_v0 *cmd = adapter->stats_cmd.va; + + return &cmd->hw_stats; + } +} + +static inline void *be_port_rxf_stats_from_cmd(struct be_adapter *adapter) +{ + if (adapter->generation == BE_GEN3) { + struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); + struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf; + + return &rxf_stats->port[adapter->port_num]; + } else { + struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); + struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf; + + return &rxf_stats->port[adapter->port_num]; + } +} + +static inline void *be_rxf_stats_from_cmd(struct be_adapter *adapter) +{ + if (adapter->generation == BE_GEN3) { + struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); + + return &hw_stats->rxf; + } else { + struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); + + return &hw_stats->rxf; + } +} + +static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter) +{ + if (adapter->generation == BE_GEN3) { + struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); + + return &hw_stats->erx; + } else { + struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); + + return &hw_stats->erx; + } +} + +static inline void *be_pmem_stats_from_cmd(struct be_adapter *adapter) +{ + if (adapter->generation == BE_GEN3) { + struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); + + return &hw_stats->pmem; + } else { + struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); + + return &hw_stats->pmem; + } +} + extern int be_pci_fnum_get(struct be_adapter *adapter); extern int be_cmd_POST(struct be_adapter *adapter); extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, @@ -1123,6 +1484,8 @@ extern int be_cmd_link_status_query(struct be_adapter *adapter, extern int be_cmd_reset(struct be_adapter *adapter); extern int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd); +extern int lancer_cmd_get_pport_stats(struct be_adapter *adapter, + struct be_dma_mem *nonemb_cmd); extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver); extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd); @@ -1149,6 +1512,11 @@ extern int be_cmd_get_beacon_state(struct be_adapter *adapter, extern int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, u32 flash_oper, u32 flash_opcode, u32 buf_size); +extern int lancer_cmd_write_object(struct be_adapter *adapter, + struct be_dma_mem *cmd, + u32 data_size, u32 data_offset, + const char *obj_name, + u32 *data_written, u8 *addn_status); int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, int offset); extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 8e770e8275d..facfe3ca5c4 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -26,8 +26,8 @@ struct be_ethtool_stat { int offset; }; -enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT, - PMEMSTAT, DRVSTAT}; +enum {NETSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT, + DRVSTAT}; #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \ offsetof(_struct, field) #define NETSTAT_INFO(field) #field, NETSTAT,\ @@ -37,15 +37,8 @@ enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT, FIELDINFO(struct be_tx_stats, field) #define DRVSTAT_RX_INFO(field) #field, DRVSTAT_RX,\ FIELDINFO(struct be_rx_stats, field) -#define MISCSTAT_INFO(field) #field, MISCSTAT,\ - FIELDINFO(struct be_rxf_stats, field) -#define PORTSTAT_INFO(field) #field, PORTSTAT,\ - FIELDINFO(struct be_port_rxf_stats, \ - field) -#define ERXSTAT_INFO(field) #field, ERXSTAT,\ - FIELDINFO(struct be_erx_stats, field) -#define PMEMSTAT_INFO(field) #field, PMEMSTAT,\ - FIELDINFO(struct be_pmem_stats, field) +#define ERXSTAT_INFO(field) #field, ERXSTAT,\ + FIELDINFO(struct be_erx_stats_v1, field) #define DRVSTAT_INFO(field) #field, DRVSTAT,\ FIELDINFO(struct be_drv_stats, \ field) @@ -65,50 +58,41 @@ static const struct be_ethtool_stat et_stats[] = { {DRVSTAT_TX_INFO(be_tx_stops)}, {DRVSTAT_TX_INFO(be_tx_events)}, {DRVSTAT_TX_INFO(be_tx_compl)}, - {PORTSTAT_INFO(rx_unicast_frames)}, - {PORTSTAT_INFO(rx_multicast_frames)}, - {PORTSTAT_INFO(rx_broadcast_frames)}, - {PORTSTAT_INFO(rx_crc_errors)}, - {PORTSTAT_INFO(rx_alignment_symbol_errors)}, - {PORTSTAT_INFO(rx_pause_frames)}, - {PORTSTAT_INFO(rx_control_frames)}, - {PORTSTAT_INFO(rx_in_range_errors)}, - {PORTSTAT_INFO(rx_out_range_errors)}, - {PORTSTAT_INFO(rx_frame_too_long)}, - {PORTSTAT_INFO(rx_address_match_errors)}, - {PORTSTAT_INFO(rx_vlan_mismatch)}, - {PORTSTAT_INFO(rx_dropped_too_small)}, - {PORTSTAT_INFO(rx_dropped_too_short)}, - {PORTSTAT_INFO(rx_dropped_header_too_small)}, - {PORTSTAT_INFO(rx_dropped_tcp_length)}, - {PORTSTAT_INFO(rx_dropped_runt)}, - {PORTSTAT_INFO(rx_fifo_overflow)}, - {PORTSTAT_INFO(rx_input_fifo_overflow)}, - {PORTSTAT_INFO(rx_ip_checksum_errs)}, - {PORTSTAT_INFO(rx_tcp_checksum_errs)}, - {PORTSTAT_INFO(rx_udp_checksum_errs)}, - {PORTSTAT_INFO(rx_non_rss_packets)}, - {PORTSTAT_INFO(rx_ipv4_packets)}, - {PORTSTAT_INFO(rx_ipv6_packets)}, - {PORTSTAT_INFO(rx_switched_unicast_packets)}, - {PORTSTAT_INFO(rx_switched_multicast_packets)}, - {PORTSTAT_INFO(rx_switched_broadcast_packets)}, - {PORTSTAT_INFO(tx_unicastframes)}, - {PORTSTAT_INFO(tx_multicastframes)}, - {PORTSTAT_INFO(tx_broadcastframes)}, - {PORTSTAT_INFO(tx_pauseframes)}, - {PORTSTAT_INFO(tx_controlframes)}, - {MISCSTAT_INFO(rx_drops_no_pbuf)}, - {MISCSTAT_INFO(rx_drops_no_txpb)}, - {MISCSTAT_INFO(rx_drops_no_erx_descr)}, - {MISCSTAT_INFO(rx_drops_no_tpre_descr)}, - {MISCSTAT_INFO(rx_drops_too_many_frags)}, - {MISCSTAT_INFO(rx_drops_invalid_ring)}, - {MISCSTAT_INFO(forwarded_packets)}, - {MISCSTAT_INFO(rx_drops_mtu)}, - {MISCSTAT_INFO(port0_jabber_events)}, - {MISCSTAT_INFO(port1_jabber_events)}, - {PMEMSTAT_INFO(eth_red_drops)}, + {DRVSTAT_INFO(rx_crc_errors)}, + {DRVSTAT_INFO(rx_alignment_symbol_errors)}, + {DRVSTAT_INFO(rx_pause_frames)}, + {DRVSTAT_INFO(rx_control_frames)}, + {DRVSTAT_INFO(rx_in_range_errors)}, + {DRVSTAT_INFO(rx_out_range_errors)}, + {DRVSTAT_INFO(rx_frame_too_long)}, + {DRVSTAT_INFO(rx_address_match_errors)}, + {DRVSTAT_INFO(rx_dropped_too_small)}, + {DRVSTAT_INFO(rx_dropped_too_short)}, + {DRVSTAT_INFO(rx_dropped_header_too_small)}, + {DRVSTAT_INFO(rx_dropped_tcp_length)}, + {DRVSTAT_INFO(rx_dropped_runt)}, + {DRVSTAT_INFO(rxpp_fifo_overflow_drop)}, + {DRVSTAT_INFO(rx_input_fifo_overflow_drop)}, + {DRVSTAT_INFO(rx_ip_checksum_errs)}, + {DRVSTAT_INFO(rx_tcp_checksum_errs)}, + {DRVSTAT_INFO(rx_udp_checksum_errs)}, + {DRVSTAT_INFO(rx_switched_unicast_packets)}, + {DRVSTAT_INFO(rx_switched_multicast_packets)}, + {DRVSTAT_INFO(rx_switched_broadcast_packets)}, + {DRVSTAT_INFO(tx_pauseframes)}, + {DRVSTAT_INFO(tx_controlframes)}, + {DRVSTAT_INFO(rx_priority_pause_frames)}, + {DRVSTAT_INFO(pmem_fifo_overflow_drop)}, + {DRVSTAT_INFO(jabber_events)}, + {DRVSTAT_INFO(rx_drops_no_pbuf)}, + {DRVSTAT_INFO(rx_drops_no_txpb)}, + {DRVSTAT_INFO(rx_drops_no_erx_descr)}, + {DRVSTAT_INFO(rx_drops_no_tpre_descr)}, + {DRVSTAT_INFO(rx_drops_too_many_frags)}, + {DRVSTAT_INFO(rx_drops_invalid_ring)}, + {DRVSTAT_INFO(forwarded_packets)}, + {DRVSTAT_INFO(rx_drops_mtu)}, + {DRVSTAT_INFO(eth_red_drops)}, {DRVSTAT_INFO(be_on_die_temperature)} }; #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats) @@ -268,8 +252,6 @@ be_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, uint64_t *data) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va); - struct be_erx_stats *erx_stats = &hw_stats->erx; struct be_rx_obj *rxo; void *p = NULL; int i, j; @@ -282,15 +264,6 @@ be_get_ethtool_stats(struct net_device *netdev, case DRVSTAT_TX: p = &adapter->tx_stats; break; - case PORTSTAT: - p = &hw_stats->rxf.port[adapter->port_num]; - break; - case MISCSTAT: - p = &hw_stats->rxf; - break; - case PMEMSTAT: - p = &hw_stats->pmem; - break; case DRVSTAT: p = &adapter->drv_stats; break; @@ -308,7 +281,8 @@ be_get_ethtool_stats(struct net_device *netdev, p = (u8 *)&rxo->stats + et_rx_stats[i].offset; break; case ERXSTAT: - p = (u32 *)erx_stats + rxo->q.id; + p = (u32 *)be_erx_stats_from_cmd(adapter) + + rxo->q.id; break; } data[ETHTOOL_STATS_NUM + j * ETHTOOL_RXSTATS_NUM + i] = diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 243172bedfa..7322a511e93 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -245,14 +245,185 @@ netdev_addr: return status; } +static void populate_be2_stats(struct be_adapter *adapter) +{ + + struct be_drv_stats *drvs = &adapter->drv_stats; + struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter); + struct be_port_rxf_stats_v0 *port_stats = + be_port_rxf_stats_from_cmd(adapter); + struct be_rxf_stats_v0 *rxf_stats = + be_rxf_stats_from_cmd(adapter); + + drvs->rx_pause_frames = port_stats->rx_pause_frames; + drvs->rx_crc_errors = port_stats->rx_crc_errors; + drvs->rx_control_frames = port_stats->rx_control_frames; + drvs->rx_in_range_errors = port_stats->rx_in_range_errors; + drvs->rx_frame_too_long = port_stats->rx_frame_too_long; + drvs->rx_dropped_runt = port_stats->rx_dropped_runt; + drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs; + drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs; + drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs; + drvs->rxpp_fifo_overflow_drop = port_stats->rx_fifo_overflow; + drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length; + drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small; + drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short; + drvs->rx_out_range_errors = port_stats->rx_out_range_errors; + drvs->rx_input_fifo_overflow_drop = + port_stats->rx_input_fifo_overflow; + drvs->rx_dropped_header_too_small = + port_stats->rx_dropped_header_too_small; + drvs->rx_address_match_errors = + port_stats->rx_address_match_errors; + drvs->rx_alignment_symbol_errors = + port_stats->rx_alignment_symbol_errors; + + drvs->tx_pauseframes = port_stats->tx_pauseframes; + drvs->tx_controlframes = port_stats->tx_controlframes; + + if (adapter->port_num) + drvs->jabber_events = + rxf_stats->port1_jabber_events; + else + drvs->jabber_events = + rxf_stats->port0_jabber_events; + drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; + drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; + drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; + drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; + drvs->forwarded_packets = rxf_stats->forwarded_packets; + drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; + drvs->rx_drops_no_tpre_descr = + rxf_stats->rx_drops_no_tpre_descr; + drvs->rx_drops_too_many_frags = + rxf_stats->rx_drops_too_many_frags; + adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops; +} + +static void populate_be3_stats(struct be_adapter *adapter) +{ + struct be_drv_stats *drvs = &adapter->drv_stats; + struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter); + + struct be_rxf_stats_v1 *rxf_stats = + be_rxf_stats_from_cmd(adapter); + struct be_port_rxf_stats_v1 *port_stats = + be_port_rxf_stats_from_cmd(adapter); + + drvs->rx_priority_pause_frames = 0; + drvs->pmem_fifo_overflow_drop = 0; + drvs->rx_pause_frames = port_stats->rx_pause_frames; + drvs->rx_crc_errors = port_stats->rx_crc_errors; + drvs->rx_control_frames = port_stats->rx_control_frames; + drvs->rx_in_range_errors = port_stats->rx_in_range_errors; + drvs->rx_frame_too_long = port_stats->rx_frame_too_long; + drvs->rx_dropped_runt = port_stats->rx_dropped_runt; + drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs; + drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs; + drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs; + drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length; + drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small; + drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short; + drvs->rx_out_range_errors = port_stats->rx_out_range_errors; + drvs->rx_dropped_header_too_small = + port_stats->rx_dropped_header_too_small; + drvs->rx_input_fifo_overflow_drop = + port_stats->rx_input_fifo_overflow_drop; + drvs->rx_address_match_errors = + port_stats->rx_address_match_errors; + drvs->rx_alignment_symbol_errors = + port_stats->rx_alignment_symbol_errors; + drvs->rxpp_fifo_overflow_drop = + port_stats->rxpp_fifo_overflow_drop; + drvs->tx_pauseframes = port_stats->tx_pauseframes; + drvs->tx_controlframes = port_stats->tx_controlframes; + drvs->jabber_events = port_stats->jabber_events; + drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; + drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; + drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; + drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; + drvs->forwarded_packets = rxf_stats->forwarded_packets; + drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; + drvs->rx_drops_no_tpre_descr = + rxf_stats->rx_drops_no_tpre_descr; + drvs->rx_drops_too_many_frags = + rxf_stats->rx_drops_too_many_frags; + adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops; +} + +static void populate_lancer_stats(struct be_adapter *adapter) +{ + + struct be_drv_stats *drvs = &adapter->drv_stats; + struct lancer_cmd_pport_stats *pport_stats = pport_stats_from_cmd + (adapter); + drvs->rx_priority_pause_frames = 0; + drvs->pmem_fifo_overflow_drop = 0; + drvs->rx_pause_frames = + make_64bit_val(pport_stats->rx_pause_frames_lo, + pport_stats->rx_pause_frames_hi); + drvs->rx_crc_errors = make_64bit_val(pport_stats->rx_crc_errors_hi, + pport_stats->rx_crc_errors_lo); + drvs->rx_control_frames = + make_64bit_val(pport_stats->rx_control_frames_hi, + pport_stats->rx_control_frames_lo); + drvs->rx_in_range_errors = pport_stats->rx_in_range_errors; + drvs->rx_frame_too_long = + make_64bit_val(pport_stats->rx_internal_mac_errors_hi, + pport_stats->rx_frames_too_long_lo); + drvs->rx_dropped_runt = pport_stats->rx_dropped_runt; + drvs->rx_ip_checksum_errs = pport_stats->rx_ip_checksum_errors; + drvs->rx_tcp_checksum_errs = pport_stats->rx_tcp_checksum_errors; + drvs->rx_udp_checksum_errs = pport_stats->rx_udp_checksum_errors; + drvs->rx_dropped_tcp_length = + pport_stats->rx_dropped_invalid_tcp_length; + drvs->rx_dropped_too_small = pport_stats->rx_dropped_too_small; + drvs->rx_dropped_too_short = pport_stats->rx_dropped_too_short; + drvs->rx_out_range_errors = pport_stats->rx_out_of_range_errors; + drvs->rx_dropped_header_too_small = + pport_stats->rx_dropped_header_too_small; + drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow; + drvs->rx_address_match_errors = pport_stats->rx_address_match_errors; + drvs->rx_alignment_symbol_errors = + make_64bit_val(pport_stats->rx_symbol_errors_hi, + pport_stats->rx_symbol_errors_lo); + drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow; + drvs->tx_pauseframes = make_64bit_val(pport_stats->tx_pause_frames_hi, + pport_stats->tx_pause_frames_lo); + drvs->tx_controlframes = + make_64bit_val(pport_stats->tx_control_frames_hi, + pport_stats->tx_control_frames_lo); + drvs->jabber_events = pport_stats->rx_jabbers; + drvs->rx_drops_no_pbuf = 0; + drvs->rx_drops_no_txpb = 0; + drvs->rx_drops_no_erx_descr = 0; + drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue; + drvs->forwarded_packets = make_64bit_val(pport_stats->num_forwards_hi, + pport_stats->num_forwards_lo); + drvs->rx_drops_mtu = make_64bit_val(pport_stats->rx_drops_mtu_hi, + pport_stats->rx_drops_mtu_lo); + drvs->rx_drops_no_tpre_descr = 0; + drvs->rx_drops_too_many_frags = + make_64bit_val(pport_stats->rx_drops_too_many_frags_hi, + pport_stats->rx_drops_too_many_frags_lo); +} + +void be_parse_stats(struct be_adapter *adapter) +{ + if (adapter->generation == BE_GEN3) { + if (lancer_chip(adapter)) + populate_lancer_stats(adapter); + else + populate_be3_stats(adapter); + } else { + populate_be2_stats(adapter); + } +} + void netdev_stats_update(struct be_adapter *adapter) { - struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va); - struct be_rxf_stats *rxf_stats = &hw_stats->rxf; - struct be_port_rxf_stats *port_stats = - &rxf_stats->port[adapter->port_num]; + struct be_drv_stats *drvs = &adapter->drv_stats; struct net_device_stats *dev_stats = &adapter->netdev->stats; - struct be_erx_stats *erx_stats = &hw_stats->erx; struct be_rx_obj *rxo; int i; @@ -262,43 +433,54 @@ void netdev_stats_update(struct be_adapter *adapter) dev_stats->rx_bytes += rx_stats(rxo)->rx_bytes; dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts; /* no space in linux buffers: best possible approximation */ - dev_stats->rx_dropped += - erx_stats->rx_drops_no_fragments[rxo->q.id]; + if (adapter->generation == BE_GEN3) { + if (!(lancer_chip(adapter))) { + struct be_erx_stats_v1 *erx_stats = + be_erx_stats_from_cmd(adapter); + dev_stats->rx_dropped += + erx_stats->rx_drops_no_fragments[rxo->q.id]; + } + } else { + struct be_erx_stats_v0 *erx_stats = + be_erx_stats_from_cmd(adapter); + dev_stats->rx_dropped += + erx_stats->rx_drops_no_fragments[rxo->q.id]; + } } dev_stats->tx_packets = tx_stats(adapter)->be_tx_pkts; dev_stats->tx_bytes = tx_stats(adapter)->be_tx_bytes; /* bad pkts received */ - dev_stats->rx_errors = port_stats->rx_crc_errors + - port_stats->rx_alignment_symbol_errors + - port_stats->rx_in_range_errors + - port_stats->rx_out_range_errors + - port_stats->rx_frame_too_long + - port_stats->rx_dropped_too_small + - port_stats->rx_dropped_too_short + - port_stats->rx_dropped_header_too_small + - port_stats->rx_dropped_tcp_length + - port_stats->rx_dropped_runt + - port_stats->rx_tcp_checksum_errs + - port_stats->rx_ip_checksum_errs + - port_stats->rx_udp_checksum_errs; + dev_stats->rx_errors = drvs->rx_crc_errors + + drvs->rx_alignment_symbol_errors + + drvs->rx_in_range_errors + + drvs->rx_out_range_errors + + drvs->rx_frame_too_long + + drvs->rx_dropped_too_small + + drvs->rx_dropped_too_short + + drvs->rx_dropped_header_too_small + + drvs->rx_dropped_tcp_length + + drvs->rx_dropped_runt + + drvs->rx_tcp_checksum_errs + + drvs->rx_ip_checksum_errs + + drvs->rx_udp_checksum_errs; /* detailed rx errors */ - dev_stats->rx_length_errors = port_stats->rx_in_range_errors + - port_stats->rx_out_range_errors + - port_stats->rx_frame_too_long; + dev_stats->rx_length_errors = drvs->rx_in_range_errors + + drvs->rx_out_range_errors + + drvs->rx_frame_too_long; - dev_stats->rx_crc_errors = port_stats->rx_crc_errors; + dev_stats->rx_crc_errors = drvs->rx_crc_errors; /* frame alignment errors */ - dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors; + dev_stats->rx_frame_errors = drvs->rx_alignment_symbol_errors; /* receiver fifo overrun */ /* drops_no_pbuf is no per i/f, it's per BE card */ - dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + - port_stats->rx_input_fifo_overflow + - rxf_stats->rx_drops_no_pbuf; + dev_stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop + + drvs->rx_input_fifo_overflow_drop + + drvs->rx_drops_no_pbuf; } void be_link_status_update(struct be_adapter *adapter, bool link_up) @@ -1901,9 +2083,13 @@ static void be_worker(struct work_struct *work) goto reschedule; } - if (!adapter->stats_cmd_sent) - be_cmd_get_stats(adapter, &adapter->stats_cmd); - + if (!adapter->stats_cmd_sent) { + if (lancer_chip(adapter)) + lancer_cmd_get_pport_stats(adapter, + &adapter->stats_cmd); + else + be_cmd_get_stats(adapter, &adapter->stats_cmd); + } be_tx_rate_update(adapter); for_all_rx_queues(adapter, rxo, i) { @@ -2526,7 +2712,6 @@ static int be_flash_data(struct be_adapter *adapter, "cmd to write to flash rom failed.\n"); return -1; } - yield(); } } return 0; @@ -2544,32 +2729,98 @@ static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr) return 0; } -int be_load_fw(struct be_adapter *adapter, u8 *func) +static int lancer_fw_download(struct be_adapter *adapter, + const struct firmware *fw) { - char fw_file[ETHTOOL_FLASH_MAX_FILENAME]; - const struct firmware *fw; - struct flash_file_hdr_g2 *fhdr; - struct flash_file_hdr_g3 *fhdr3; - struct image_hdr *img_hdr_ptr = NULL; +#define LANCER_FW_DOWNLOAD_CHUNK (32 * 1024) +#define LANCER_FW_DOWNLOAD_LOCATION "/prg" struct be_dma_mem flash_cmd; - int status, i = 0, num_imgs = 0; - const u8 *p; + struct lancer_cmd_req_write_object *req; + const u8 *data_ptr = NULL; + u8 *dest_image_ptr = NULL; + size_t image_size = 0; + u32 chunk_size = 0; + u32 data_written = 0; + u32 offset = 0; + int status = 0; + u8 add_status = 0; - if (!netif_running(adapter->netdev)) { + if (!IS_ALIGNED(fw->size, sizeof(u32))) { dev_err(&adapter->pdev->dev, - "Firmware load not allowed (interface is down)\n"); - return -EPERM; + "FW Image not properly aligned. " + "Length must be 4 byte aligned.\n"); + status = -EINVAL; + goto lancer_fw_exit; } - strcpy(fw_file, func); + flash_cmd.size = sizeof(struct lancer_cmd_req_write_object) + + LANCER_FW_DOWNLOAD_CHUNK; + flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, + &flash_cmd.dma, GFP_KERNEL); + if (!flash_cmd.va) { + status = -ENOMEM; + dev_err(&adapter->pdev->dev, + "Memory allocation failure while flashing\n"); + goto lancer_fw_exit; + } - status = request_firmware(&fw, fw_file, &adapter->pdev->dev); - if (status) - goto fw_exit; + req = flash_cmd.va; + dest_image_ptr = flash_cmd.va + + sizeof(struct lancer_cmd_req_write_object); + image_size = fw->size; + data_ptr = fw->data; + + while (image_size) { + chunk_size = min_t(u32, image_size, LANCER_FW_DOWNLOAD_CHUNK); + + /* Copy the image chunk content. */ + memcpy(dest_image_ptr, data_ptr, chunk_size); + + status = lancer_cmd_write_object(adapter, &flash_cmd, + chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION, + &data_written, &add_status); + + if (status) + break; + + offset += data_written; + data_ptr += data_written; + image_size -= data_written; + } + + if (!status) { + /* Commit the FW written */ + status = lancer_cmd_write_object(adapter, &flash_cmd, + 0, offset, LANCER_FW_DOWNLOAD_LOCATION, + &data_written, &add_status); + } + + dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va, + flash_cmd.dma); + if (status) { + dev_err(&adapter->pdev->dev, + "Firmware load error. " + "Status code: 0x%x Additional Status: 0x%x\n", + status, add_status); + goto lancer_fw_exit; + } + + dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); +lancer_fw_exit: + return status; +} + +static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw) +{ + struct flash_file_hdr_g2 *fhdr; + struct flash_file_hdr_g3 *fhdr3; + struct image_hdr *img_hdr_ptr = NULL; + struct be_dma_mem flash_cmd; + const u8 *p; + int status = 0, i = 0, num_imgs = 0; p = fw->data; fhdr = (struct flash_file_hdr_g2 *) p; - dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file); flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024; flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, @@ -2578,7 +2829,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) status = -ENOMEM; dev_err(&adapter->pdev->dev, "Memory allocation failure while flashing\n"); - goto fw_exit; + goto be_fw_exit; } if ((adapter->generation == BE_GEN3) && @@ -2606,11 +2857,37 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) flash_cmd.dma); if (status) { dev_err(&adapter->pdev->dev, "Firmware load error\n"); - goto fw_exit; + goto be_fw_exit; } dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); +be_fw_exit: + return status; +} + +int be_load_fw(struct be_adapter *adapter, u8 *fw_file) +{ + const struct firmware *fw; + int status; + + if (!netif_running(adapter->netdev)) { + dev_err(&adapter->pdev->dev, + "Firmware load not allowed (interface is down)\n"); + return -1; + } + + status = request_firmware(&fw, fw_file, &adapter->pdev->dev); + if (status) + goto fw_exit; + + dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file); + + if (lancer_chip(adapter)) + status = lancer_fw_download(adapter, fw); + else + status = be_fw_download(adapter, fw); + fw_exit: release_firmware(fw); return status; @@ -2823,7 +3100,14 @@ static int be_stats_init(struct be_adapter *adapter) { struct be_dma_mem *cmd = &adapter->stats_cmd; - cmd->size = sizeof(struct be_cmd_req_get_stats); + if (adapter->generation == BE_GEN2) { + cmd->size = sizeof(struct be_cmd_req_get_stats_v0); + } else { + if (lancer_chip(adapter)) + cmd->size = sizeof(struct lancer_cmd_req_pport_stats); + else + cmd->size = sizeof(struct be_cmd_req_get_stats_v1); + } cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma, GFP_KERNEL); if (cmd->va == NULL) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 6ee6601b517..ca2bbc0e5d4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -2840,15 +2840,31 @@ int bnx2x_set_features(struct net_device *dev, u32 features) { struct bnx2x *bp = netdev_priv(dev); u32 flags = bp->flags; + bool bnx2x_reload = false; if (features & NETIF_F_LRO) flags |= TPA_ENABLE_FLAG; else flags &= ~TPA_ENABLE_FLAG; + if (features & NETIF_F_LOOPBACK) { + if (bp->link_params.loopback_mode != LOOPBACK_BMAC) { + bp->link_params.loopback_mode = LOOPBACK_BMAC; + bnx2x_reload = true; + } + } else { + if (bp->link_params.loopback_mode != LOOPBACK_NONE) { + bp->link_params.loopback_mode = LOOPBACK_NONE; + bnx2x_reload = true; + } + } + if (flags ^ bp->flags) { bp->flags = flags; + bnx2x_reload = true; + } + if (bnx2x_reload) { if (bp->recovery_state == BNX2X_RECOVERY_DONE) return bnx2x_reload_if_running(dev); /* else: bnx2x_nic_load() will be called at end of recovery */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 2762edf956e..f45c0caf324 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -9273,6 +9273,9 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, if (bp->flags & USING_DAC_FLAG) dev->features |= NETIF_F_HIGHDMA; + /* Add Loopback capability to the device */ + dev->hw_features |= NETIF_F_LOOPBACK; + #ifdef BCM_DCBNL dev->dcbnl_ops = &bnx2x_dcbnl_ops; #endif |