Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'support-some-enhances-features-for-the-hibmcge-driver'

Jijie Shao says:

====================
Support some enhances features for the HIBMCGE driver

In this patch set, we mainly implement some enhanced features.
It mainly includes the statistics, diagnosis, and ioctl to
improve fault locating efficiency,
abnormal irq and MAC link exception handling feature
to enhance driver robustness,
and rx checksum offload feature to improve performance
(tx checksum feature has been implemented).

v3: https://lore.kernel.org/all/20250221115526.1082660-2-shaojijie@huawei.com/
v2: https://lore.kernel.org/all/20250218085829.3172126-1-shaojijie@huawei.com/
v1: https://lore.kernel.org/all/20250213035529.2402283-1-shaojijie@huawei.com/
====================

Link: https://patch.msgid.link/20250228115411.1750803-1-shaojijie@huawei.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+1304 -26
+1 -1
drivers/net/ethernet/hisilicon/hibmcge/Makefile
··· 6 6 obj-$(CONFIG_HIBMCGE) += hibmcge.o 7 7 8 8 hibmcge-objs = hbg_main.o hbg_hw.o hbg_mdio.o hbg_irq.o hbg_txrx.o hbg_ethtool.o \ 9 - hbg_debugfs.o hbg_err.o 9 + hbg_debugfs.o hbg_err.o hbg_diagnose.o
+122
drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h
··· 36 36 HBG_NIC_STATE_EVENT_HANDLING = 0, 37 37 HBG_NIC_STATE_RESETTING, 38 38 HBG_NIC_STATE_RESET_FAIL, 39 + HBG_NIC_STATE_NEED_RESET, /* trigger a reset in scheduled task */ 40 + HBG_NIC_STATE_NP_LINK_FAIL, 39 41 }; 40 42 41 43 enum hbg_reset_type { ··· 83 81 HBG_HW_EVENT_NONE = 0, 84 82 HBG_HW_EVENT_INIT, /* driver is loading */ 85 83 HBG_HW_EVENT_RESET, 84 + HBG_HW_EVENT_CORE_RESET, 86 85 }; 87 86 88 87 struct hbg_dev_specs { ··· 107 104 u32 mask; 108 105 bool re_enable; 109 106 bool need_print; 107 + bool need_reset; 110 108 u64 count; 111 109 112 110 void (*irq_handle)(struct hbg_priv *priv, struct hbg_irq_info *info); ··· 146 142 struct ethtool_pauseparam pause_param; 147 143 }; 148 144 145 + struct hbg_stats { 146 + u64 rx_desc_drop; 147 + u64 rx_desc_l2_err_cnt; 148 + u64 rx_desc_pkt_len_err_cnt; 149 + u64 rx_desc_l3l4_err_cnt; 150 + u64 rx_desc_l3_wrong_head_cnt; 151 + u64 rx_desc_l3_csum_err_cnt; 152 + u64 rx_desc_l3_len_err_cnt; 153 + u64 rx_desc_l3_zero_ttl_cnt; 154 + u64 rx_desc_l3_other_cnt; 155 + u64 rx_desc_l4_err_cnt; 156 + u64 rx_desc_l4_wrong_head_cnt; 157 + u64 rx_desc_l4_len_err_cnt; 158 + u64 rx_desc_l4_csum_err_cnt; 159 + u64 rx_desc_l4_zero_port_num_cnt; 160 + u64 rx_desc_l4_other_cnt; 161 + u64 rx_desc_frag_cnt; 162 + u64 rx_desc_ip_ver_err_cnt; 163 + u64 rx_desc_ipv4_pkt_cnt; 164 + u64 rx_desc_ipv6_pkt_cnt; 165 + u64 rx_desc_no_ip_pkt_cnt; 166 + u64 rx_desc_ip_pkt_cnt; 167 + u64 rx_desc_tcp_pkt_cnt; 168 + u64 rx_desc_udp_pkt_cnt; 169 + u64 rx_desc_vlan_pkt_cnt; 170 + u64 rx_desc_icmp_pkt_cnt; 171 + u64 rx_desc_arp_pkt_cnt; 172 + u64 rx_desc_rarp_pkt_cnt; 173 + u64 rx_desc_multicast_pkt_cnt; 174 + u64 rx_desc_broadcast_pkt_cnt; 175 + u64 rx_desc_ipsec_pkt_cnt; 176 + u64 rx_desc_ip_opt_pkt_cnt; 177 + u64 rx_desc_key_not_match_cnt; 178 + 179 + u64 rx_octets_total_ok_cnt; 180 + u64 rx_uc_pkt_cnt; 181 + u64 rx_mc_pkt_cnt; 182 + u64 rx_bc_pkt_cnt; 183 + u64 rx_vlan_pkt_cnt; 184 + u64 rx_octets_bad_cnt; 185 + u64 rx_octets_total_filt_cnt; 186 + u64 rx_filt_pkt_cnt; 187 + u64 rx_trans_pkt_cnt; 188 + u64 rx_framesize_64; 189 + u64 rx_framesize_65_127; 190 + u64 rx_framesize_128_255; 191 + u64 rx_framesize_256_511; 192 + u64 rx_framesize_512_1023; 193 + u64 rx_framesize_1024_1518; 194 + u64 rx_framesize_bt_1518; 195 + u64 rx_fcs_error_cnt; 196 + u64 rx_data_error_cnt; 197 + u64 rx_align_error_cnt; 198 + u64 rx_pause_macctl_frame_cnt; 199 + u64 rx_unknown_macctl_frame_cnt; 200 + /* crc ok, > max_frm_size, < 2max_frm_size */ 201 + u64 rx_frame_long_err_cnt; 202 + /* crc fail, > max_frm_size, < 2max_frm_size */ 203 + u64 rx_jabber_err_cnt; 204 + /* > 2max_frm_size */ 205 + u64 rx_frame_very_long_err_cnt; 206 + /* < 64byte, >= short_runts_thr */ 207 + u64 rx_frame_runt_err_cnt; 208 + /* < short_runts_thr */ 209 + u64 rx_frame_short_err_cnt; 210 + /* PCU: dropped when the RX FIFO is full.*/ 211 + u64 rx_overflow_cnt; 212 + /* GMAC: the count of overflows of the RX FIFO */ 213 + u64 rx_overrun_cnt; 214 + /* PCU: the count of buffer alloc errors in RX */ 215 + u64 rx_bufrq_err_cnt; 216 + /* PCU: the count of write descriptor errors in RX */ 217 + u64 rx_we_err_cnt; 218 + /* GMAC: the count of pkts that contain PAD but length is not 64 */ 219 + u64 rx_lengthfield_err_cnt; 220 + u64 rx_fail_comma_cnt; 221 + 222 + u64 rx_dma_err_cnt; 223 + u64 rx_fifo_less_empty_thrsld_cnt; 224 + 225 + u64 tx_octets_total_ok_cnt; 226 + u64 tx_uc_pkt_cnt; 227 + u64 tx_mc_pkt_cnt; 228 + u64 tx_bc_pkt_cnt; 229 + u64 tx_vlan_pkt_cnt; 230 + u64 tx_octets_bad_cnt; 231 + u64 tx_trans_pkt_cnt; 232 + u64 tx_pause_frame_cnt; 233 + u64 tx_framesize_64; 234 + u64 tx_framesize_65_127; 235 + u64 tx_framesize_128_255; 236 + u64 tx_framesize_256_511; 237 + u64 tx_framesize_512_1023; 238 + u64 tx_framesize_1024_1518; 239 + u64 tx_framesize_bt_1518; 240 + /* GMAC: the count of times that frames fail to be transmitted 241 + * due to internal errors. 242 + */ 243 + u64 tx_underrun_err_cnt; 244 + u64 tx_add_cs_fail_cnt; 245 + /* PCU: the count of buffer free errors in TX */ 246 + u64 tx_bufrl_err_cnt; 247 + u64 tx_crc_err_cnt; 248 + u64 tx_drop_cnt; 249 + u64 tx_excessive_length_drop_cnt; 250 + 251 + u64 tx_timeout_cnt; 252 + u64 tx_dma_err_cnt; 253 + 254 + u64 np_link_fail_cnt; 255 + }; 256 + 149 257 struct hbg_priv { 150 258 struct net_device *netdev; 151 259 struct pci_dev *pdev; ··· 271 155 struct hbg_mac_filter filter; 272 156 enum hbg_reset_type reset_type; 273 157 struct hbg_user_def user_def; 158 + struct hbg_stats stats; 159 + unsigned long last_update_stats_time; 160 + struct delayed_work service_task; 274 161 }; 162 + 163 + void hbg_err_reset_task_schedule(struct hbg_priv *priv); 164 + void hbg_np_link_fail_task_schedule(struct hbg_priv *priv); 275 165 276 166 #endif
+6 -1
drivers/net/ethernet/hisilicon/hibmcge/hbg_debugfs.c
··· 67 67 for (i = 0; i < priv->vectors.info_array_len; i++) { 68 68 info = &priv->vectors.info_array[i]; 69 69 seq_printf(s, 70 - "%-20s: enabled: %-5s, logged: %-5s, count: %llu\n", 70 + "%-20s: enabled: %-5s, reset: %-5s, logged: %-5s, count: %llu\n", 71 71 info->name, 72 72 str_true_false(hbg_hw_irq_is_enabled(priv, 73 73 info->mask)), 74 + str_true_false(info->need_reset), 74 75 str_true_false(info->need_print), 75 76 info->count); 76 77 } ··· 115 114 state_str_true_false(priv, HBG_NIC_STATE_RESET_FAIL)); 116 115 seq_printf(s, "last reset type: %s\n", 117 116 reset_type_str[priv->reset_type]); 117 + seq_printf(s, "need reset state: %s\n", 118 + state_str_true_false(priv, HBG_NIC_STATE_NEED_RESET)); 119 + seq_printf(s, "np_link fail state: %s\n", 120 + state_str_true_false(priv, HBG_NIC_STATE_NP_LINK_FAIL)); 118 121 119 122 return 0; 120 123 }
+348
drivers/net/ethernet/hisilicon/hibmcge/hbg_diagnose.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // Copyright (c) 2025 Hisilicon Limited. 3 + 4 + #include <linux/iopoll.h> 5 + #include <linux/phy.h> 6 + #include "hbg_common.h" 7 + #include "hbg_ethtool.h" 8 + #include "hbg_hw.h" 9 + #include "hbg_diagnose.h" 10 + 11 + #define HBG_MSG_DATA_MAX_NUM 64 12 + 13 + struct hbg_diagnose_message { 14 + u32 opcode; 15 + u32 status; 16 + u32 data_num; 17 + struct hbg_priv *priv; 18 + 19 + u32 data[HBG_MSG_DATA_MAX_NUM]; 20 + }; 21 + 22 + #define HBG_HW_PUSH_WAIT_TIMEOUT_US (2 * 1000 * 1000) 23 + #define HBG_HW_PUSH_WAIT_INTERVAL_US (1 * 1000) 24 + 25 + enum hbg_push_cmd { 26 + HBG_PUSH_CMD_IRQ = 0, 27 + HBG_PUSH_CMD_STATS, 28 + HBG_PUSH_CMD_LINK, 29 + }; 30 + 31 + struct hbg_push_stats_info { 32 + /* id is used to match the name of the current stats item. 33 + * and is used for pretty print on BMC 34 + */ 35 + u32 id; 36 + u64 offset; 37 + }; 38 + 39 + struct hbg_push_irq_info { 40 + /* id is used to match the name of the current irq. 41 + * and is used for pretty print on BMC 42 + */ 43 + u32 id; 44 + u32 mask; 45 + }; 46 + 47 + #define HBG_PUSH_IRQ_I(name, id) {id, HBG_INT_MSK_##name##_B} 48 + static const struct hbg_push_irq_info hbg_push_irq_list[] = { 49 + HBG_PUSH_IRQ_I(RX, 0), 50 + HBG_PUSH_IRQ_I(TX, 1), 51 + HBG_PUSH_IRQ_I(TX_PKT_CPL, 2), 52 + HBG_PUSH_IRQ_I(MAC_MII_FIFO_ERR, 3), 53 + HBG_PUSH_IRQ_I(MAC_PCS_RX_FIFO_ERR, 4), 54 + HBG_PUSH_IRQ_I(MAC_PCS_TX_FIFO_ERR, 5), 55 + HBG_PUSH_IRQ_I(MAC_APP_RX_FIFO_ERR, 6), 56 + HBG_PUSH_IRQ_I(MAC_APP_TX_FIFO_ERR, 7), 57 + HBG_PUSH_IRQ_I(SRAM_PARITY_ERR, 8), 58 + HBG_PUSH_IRQ_I(TX_AHB_ERR, 9), 59 + HBG_PUSH_IRQ_I(RX_BUF_AVL, 10), 60 + HBG_PUSH_IRQ_I(REL_BUF_ERR, 11), 61 + HBG_PUSH_IRQ_I(TXCFG_AVL, 12), 62 + HBG_PUSH_IRQ_I(TX_DROP, 13), 63 + HBG_PUSH_IRQ_I(RX_DROP, 14), 64 + HBG_PUSH_IRQ_I(RX_AHB_ERR, 15), 65 + HBG_PUSH_IRQ_I(MAC_FIFO_ERR, 16), 66 + HBG_PUSH_IRQ_I(RBREQ_ERR, 17), 67 + HBG_PUSH_IRQ_I(WE_ERR, 18), 68 + }; 69 + 70 + #define HBG_PUSH_STATS_I(name, id) {id, HBG_STATS_FIELD_OFF(name)} 71 + static const struct hbg_push_stats_info hbg_push_stats_list[] = { 72 + HBG_PUSH_STATS_I(rx_desc_drop, 0), 73 + HBG_PUSH_STATS_I(rx_desc_l2_err_cnt, 1), 74 + HBG_PUSH_STATS_I(rx_desc_pkt_len_err_cnt, 2), 75 + HBG_PUSH_STATS_I(rx_desc_l3_wrong_head_cnt, 3), 76 + HBG_PUSH_STATS_I(rx_desc_l3_csum_err_cnt, 4), 77 + HBG_PUSH_STATS_I(rx_desc_l3_len_err_cnt, 5), 78 + HBG_PUSH_STATS_I(rx_desc_l3_zero_ttl_cnt, 6), 79 + HBG_PUSH_STATS_I(rx_desc_l3_other_cnt, 7), 80 + HBG_PUSH_STATS_I(rx_desc_l4_err_cnt, 8), 81 + HBG_PUSH_STATS_I(rx_desc_l4_wrong_head_cnt, 9), 82 + HBG_PUSH_STATS_I(rx_desc_l4_len_err_cnt, 10), 83 + HBG_PUSH_STATS_I(rx_desc_l4_csum_err_cnt, 11), 84 + HBG_PUSH_STATS_I(rx_desc_l4_zero_port_num_cnt, 12), 85 + HBG_PUSH_STATS_I(rx_desc_l4_other_cnt, 13), 86 + HBG_PUSH_STATS_I(rx_desc_frag_cnt, 14), 87 + HBG_PUSH_STATS_I(rx_desc_ip_ver_err_cnt, 15), 88 + HBG_PUSH_STATS_I(rx_desc_ipv4_pkt_cnt, 16), 89 + HBG_PUSH_STATS_I(rx_desc_ipv6_pkt_cnt, 17), 90 + HBG_PUSH_STATS_I(rx_desc_no_ip_pkt_cnt, 18), 91 + HBG_PUSH_STATS_I(rx_desc_ip_pkt_cnt, 19), 92 + HBG_PUSH_STATS_I(rx_desc_tcp_pkt_cnt, 20), 93 + HBG_PUSH_STATS_I(rx_desc_udp_pkt_cnt, 21), 94 + HBG_PUSH_STATS_I(rx_desc_vlan_pkt_cnt, 22), 95 + HBG_PUSH_STATS_I(rx_desc_icmp_pkt_cnt, 23), 96 + HBG_PUSH_STATS_I(rx_desc_arp_pkt_cnt, 24), 97 + HBG_PUSH_STATS_I(rx_desc_rarp_pkt_cnt, 25), 98 + HBG_PUSH_STATS_I(rx_desc_multicast_pkt_cnt, 26), 99 + HBG_PUSH_STATS_I(rx_desc_broadcast_pkt_cnt, 27), 100 + HBG_PUSH_STATS_I(rx_desc_ipsec_pkt_cnt, 28), 101 + HBG_PUSH_STATS_I(rx_desc_ip_opt_pkt_cnt, 29), 102 + HBG_PUSH_STATS_I(rx_desc_key_not_match_cnt, 30), 103 + HBG_PUSH_STATS_I(rx_octets_total_ok_cnt, 31), 104 + HBG_PUSH_STATS_I(rx_uc_pkt_cnt, 32), 105 + HBG_PUSH_STATS_I(rx_mc_pkt_cnt, 33), 106 + HBG_PUSH_STATS_I(rx_bc_pkt_cnt, 34), 107 + HBG_PUSH_STATS_I(rx_vlan_pkt_cnt, 35), 108 + HBG_PUSH_STATS_I(rx_octets_bad_cnt, 36), 109 + HBG_PUSH_STATS_I(rx_octets_total_filt_cnt, 37), 110 + HBG_PUSH_STATS_I(rx_filt_pkt_cnt, 38), 111 + HBG_PUSH_STATS_I(rx_trans_pkt_cnt, 39), 112 + HBG_PUSH_STATS_I(rx_framesize_64, 40), 113 + HBG_PUSH_STATS_I(rx_framesize_65_127, 41), 114 + HBG_PUSH_STATS_I(rx_framesize_128_255, 42), 115 + HBG_PUSH_STATS_I(rx_framesize_256_511, 43), 116 + HBG_PUSH_STATS_I(rx_framesize_512_1023, 44), 117 + HBG_PUSH_STATS_I(rx_framesize_1024_1518, 45), 118 + HBG_PUSH_STATS_I(rx_framesize_bt_1518, 46), 119 + HBG_PUSH_STATS_I(rx_fcs_error_cnt, 47), 120 + HBG_PUSH_STATS_I(rx_data_error_cnt, 48), 121 + HBG_PUSH_STATS_I(rx_align_error_cnt, 49), 122 + HBG_PUSH_STATS_I(rx_frame_long_err_cnt, 50), 123 + HBG_PUSH_STATS_I(rx_jabber_err_cnt, 51), 124 + HBG_PUSH_STATS_I(rx_pause_macctl_frame_cnt, 52), 125 + HBG_PUSH_STATS_I(rx_unknown_macctl_frame_cnt, 53), 126 + HBG_PUSH_STATS_I(rx_frame_very_long_err_cnt, 54), 127 + HBG_PUSH_STATS_I(rx_frame_runt_err_cnt, 55), 128 + HBG_PUSH_STATS_I(rx_frame_short_err_cnt, 56), 129 + HBG_PUSH_STATS_I(rx_overflow_cnt, 57), 130 + HBG_PUSH_STATS_I(rx_bufrq_err_cnt, 58), 131 + HBG_PUSH_STATS_I(rx_we_err_cnt, 59), 132 + HBG_PUSH_STATS_I(rx_overrun_cnt, 60), 133 + HBG_PUSH_STATS_I(rx_lengthfield_err_cnt, 61), 134 + HBG_PUSH_STATS_I(rx_fail_comma_cnt, 62), 135 + HBG_PUSH_STATS_I(rx_dma_err_cnt, 63), 136 + HBG_PUSH_STATS_I(rx_fifo_less_empty_thrsld_cnt, 64), 137 + HBG_PUSH_STATS_I(tx_octets_total_ok_cnt, 65), 138 + HBG_PUSH_STATS_I(tx_uc_pkt_cnt, 66), 139 + HBG_PUSH_STATS_I(tx_mc_pkt_cnt, 67), 140 + HBG_PUSH_STATS_I(tx_bc_pkt_cnt, 68), 141 + HBG_PUSH_STATS_I(tx_vlan_pkt_cnt, 69), 142 + HBG_PUSH_STATS_I(tx_octets_bad_cnt, 70), 143 + HBG_PUSH_STATS_I(tx_trans_pkt_cnt, 71), 144 + HBG_PUSH_STATS_I(tx_pause_frame_cnt, 72), 145 + HBG_PUSH_STATS_I(tx_framesize_64, 73), 146 + HBG_PUSH_STATS_I(tx_framesize_65_127, 74), 147 + HBG_PUSH_STATS_I(tx_framesize_128_255, 75), 148 + HBG_PUSH_STATS_I(tx_framesize_256_511, 76), 149 + HBG_PUSH_STATS_I(tx_framesize_512_1023, 77), 150 + HBG_PUSH_STATS_I(tx_framesize_1024_1518, 78), 151 + HBG_PUSH_STATS_I(tx_framesize_bt_1518, 79), 152 + HBG_PUSH_STATS_I(tx_underrun_err_cnt, 80), 153 + HBG_PUSH_STATS_I(tx_add_cs_fail_cnt, 81), 154 + HBG_PUSH_STATS_I(tx_bufrl_err_cnt, 82), 155 + HBG_PUSH_STATS_I(tx_crc_err_cnt, 83), 156 + HBG_PUSH_STATS_I(tx_drop_cnt, 84), 157 + HBG_PUSH_STATS_I(tx_excessive_length_drop_cnt, 85), 158 + HBG_PUSH_STATS_I(tx_dma_err_cnt, 86), 159 + }; 160 + 161 + static int hbg_push_msg_send(struct hbg_priv *priv, 162 + struct hbg_diagnose_message *msg) 163 + { 164 + u32 header = 0; 165 + u32 i; 166 + 167 + if (msg->data_num == 0) 168 + return 0; 169 + 170 + for (i = 0; i < msg->data_num && i < HBG_MSG_DATA_MAX_NUM; i++) 171 + hbg_reg_write(priv, 172 + HBG_REG_MSG_DATA_BASE_ADDR + i * sizeof(u32), 173 + msg->data[i]); 174 + 175 + hbg_field_modify(header, HBG_REG_MSG_HEADER_OPCODE_M, msg->opcode); 176 + hbg_field_modify(header, HBG_REG_MSG_HEADER_DATA_NUM_M, msg->data_num); 177 + hbg_field_modify(header, HBG_REG_MSG_HEADER_RESP_CODE_M, ETIMEDOUT); 178 + 179 + /* start status */ 180 + hbg_field_modify(header, HBG_REG_MSG_HEADER_STATUS_M, 1); 181 + 182 + /* write header msg to start push */ 183 + hbg_reg_write(priv, HBG_REG_MSG_HEADER_ADDR, header); 184 + 185 + /* wait done */ 186 + readl_poll_timeout(priv->io_base + HBG_REG_MSG_HEADER_ADDR, header, 187 + !FIELD_GET(HBG_REG_MSG_HEADER_STATUS_M, header), 188 + HBG_HW_PUSH_WAIT_INTERVAL_US, 189 + HBG_HW_PUSH_WAIT_TIMEOUT_US); 190 + 191 + msg->status = FIELD_GET(HBG_REG_MSG_HEADER_STATUS_M, header); 192 + return -(int)FIELD_GET(HBG_REG_MSG_HEADER_RESP_CODE_M, header); 193 + } 194 + 195 + static int hbg_push_data(struct hbg_priv *priv, 196 + u32 opcode, u32 *data, u32 data_num) 197 + { 198 + struct hbg_diagnose_message msg = {0}; 199 + u32 data_left_num; 200 + u32 i, j; 201 + int ret; 202 + 203 + msg.priv = priv; 204 + msg.opcode = opcode; 205 + for (i = 0; i < data_num / HBG_MSG_DATA_MAX_NUM + 1; i++) { 206 + if (i * HBG_MSG_DATA_MAX_NUM >= data_num) 207 + break; 208 + 209 + data_left_num = data_num - i * HBG_MSG_DATA_MAX_NUM; 210 + for (j = 0; j < data_left_num && j < HBG_MSG_DATA_MAX_NUM; j++) 211 + msg.data[j] = data[i * HBG_MSG_DATA_MAX_NUM + j]; 212 + 213 + msg.data_num = j; 214 + ret = hbg_push_msg_send(priv, &msg); 215 + if (ret) 216 + return ret; 217 + } 218 + 219 + return 0; 220 + } 221 + 222 + static int hbg_push_data_u64(struct hbg_priv *priv, u32 opcode, 223 + u64 *data, u32 data_num) 224 + { 225 + /* The length of u64 is twice that of u32, 226 + * the data_num must be multiplied by 2. 227 + */ 228 + return hbg_push_data(priv, opcode, (u32 *)data, data_num * 2); 229 + } 230 + 231 + static u64 hbg_get_irq_stats(struct hbg_vector *vectors, u32 mask) 232 + { 233 + u32 i = 0; 234 + 235 + for (i = 0; i < vectors->info_array_len; i++) 236 + if (vectors->info_array[i].mask == mask) 237 + return vectors->info_array[i].count; 238 + 239 + return 0; 240 + } 241 + 242 + static int hbg_push_irq_cnt(struct hbg_priv *priv) 243 + { 244 + /* An id needs to be added for each data. 245 + * Therefore, the data_num must be multiplied by 2. 246 + */ 247 + u32 data_num = ARRAY_SIZE(hbg_push_irq_list) * 2; 248 + struct hbg_vector *vectors = &priv->vectors; 249 + const struct hbg_push_irq_info *info; 250 + u32 i, j = 0; 251 + u64 *data; 252 + int ret; 253 + 254 + data = kcalloc(data_num, sizeof(u64), GFP_KERNEL); 255 + if (!data) 256 + return -ENOMEM; 257 + 258 + /* An id needs to be added for each data. 259 + * So i + 2 for each loop. 260 + */ 261 + for (i = 0; i < data_num; i += 2) { 262 + info = &hbg_push_irq_list[j++]; 263 + data[i] = info->id; 264 + data[i + 1] = hbg_get_irq_stats(vectors, info->mask); 265 + } 266 + 267 + ret = hbg_push_data_u64(priv, HBG_PUSH_CMD_IRQ, data, data_num); 268 + kfree(data); 269 + return ret; 270 + } 271 + 272 + static int hbg_push_link_status(struct hbg_priv *priv) 273 + { 274 + u32 link_status[2]; 275 + 276 + /* phy link status */ 277 + link_status[0] = priv->mac.phydev->link; 278 + /* mac link status */ 279 + link_status[1] = hbg_reg_read_field(priv, HBG_REG_AN_NEG_STATE_ADDR, 280 + HBG_REG_AN_NEG_STATE_NP_LINK_OK_B); 281 + 282 + return hbg_push_data(priv, HBG_PUSH_CMD_LINK, 283 + link_status, ARRAY_SIZE(link_status)); 284 + } 285 + 286 + static int hbg_push_stats(struct hbg_priv *priv) 287 + { 288 + /* An id needs to be added for each data. 289 + * Therefore, the data_num must be multiplied by 2. 290 + */ 291 + u64 data_num = ARRAY_SIZE(hbg_push_stats_list) * 2; 292 + struct hbg_stats *stats = &priv->stats; 293 + const struct hbg_push_stats_info *info; 294 + u32 i, j = 0; 295 + u64 *data; 296 + int ret; 297 + 298 + data = kcalloc(data_num, sizeof(u64), GFP_KERNEL); 299 + if (!data) 300 + return -ENOMEM; 301 + 302 + /* An id needs to be added for each data. 303 + * So i + 2 for each loop. 304 + */ 305 + for (i = 0; i < data_num; i += 2) { 306 + info = &hbg_push_stats_list[j++]; 307 + data[i] = info->id; 308 + data[i + 1] = HBG_STATS_R(stats, info->offset); 309 + } 310 + 311 + ret = hbg_push_data_u64(priv, HBG_PUSH_CMD_STATS, data, data_num); 312 + kfree(data); 313 + return ret; 314 + } 315 + 316 + void hbg_diagnose_message_push(struct hbg_priv *priv) 317 + { 318 + int ret; 319 + 320 + if (test_bit(HBG_NIC_STATE_RESETTING, &priv->state)) 321 + return; 322 + 323 + /* only 1 is the right value */ 324 + if (hbg_reg_read(priv, HBG_REG_PUSH_REQ_ADDR) != 1) 325 + return; 326 + 327 + ret = hbg_push_irq_cnt(priv); 328 + if (ret) { 329 + dev_err(&priv->pdev->dev, 330 + "failed to push irq cnt, ret = %d\n", ret); 331 + goto push_done; 332 + } 333 + 334 + ret = hbg_push_link_status(priv); 335 + if (ret) { 336 + dev_err(&priv->pdev->dev, 337 + "failed to push link status, ret = %d\n", ret); 338 + goto push_done; 339 + } 340 + 341 + ret = hbg_push_stats(priv); 342 + if (ret) 343 + dev_err(&priv->pdev->dev, 344 + "failed to push stats, ret = %d\n", ret); 345 + 346 + push_done: 347 + hbg_reg_write(priv, HBG_REG_PUSH_REQ_ADDR, 0); 348 + }
+11
drivers/net/ethernet/hisilicon/hibmcge/hbg_diagnose.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Copyright (c) 2025 Hisilicon Limited. */ 3 + 4 + #ifndef __HBG_DIAGNOSE_H 5 + #define __HBG_DIAGNOSE_H 6 + 7 + #include "hbg_common.h" 8 + 9 + void hbg_diagnose_message_push(struct hbg_priv *priv); 10 + 11 + #endif
+58
drivers/net/ethernet/hisilicon/hibmcge/hbg_err.c
··· 105 105 return hbg_reset_done(priv, HBG_RESET_TYPE_FUNCTION); 106 106 } 107 107 108 + void hbg_err_reset(struct hbg_priv *priv) 109 + { 110 + bool running; 111 + 112 + rtnl_lock(); 113 + running = netif_running(priv->netdev); 114 + if (running) 115 + dev_close(priv->netdev); 116 + 117 + hbg_reset(priv); 118 + 119 + /* in hbg_pci_err_detected(), we will detach first, 120 + * so we need to attach before open 121 + */ 122 + if (!netif_device_present(priv->netdev)) 123 + netif_device_attach(priv->netdev); 124 + 125 + if (running) 126 + dev_open(priv->netdev, NULL); 127 + rtnl_unlock(); 128 + } 129 + 130 + static pci_ers_result_t hbg_pci_err_detected(struct pci_dev *pdev, 131 + pci_channel_state_t state) 132 + { 133 + struct net_device *netdev = pci_get_drvdata(pdev); 134 + 135 + netif_device_detach(netdev); 136 + 137 + if (state == pci_channel_io_perm_failure) 138 + return PCI_ERS_RESULT_DISCONNECT; 139 + 140 + pci_disable_device(pdev); 141 + return PCI_ERS_RESULT_NEED_RESET; 142 + } 143 + 144 + static pci_ers_result_t hbg_pci_err_slot_reset(struct pci_dev *pdev) 145 + { 146 + struct net_device *netdev = pci_get_drvdata(pdev); 147 + struct hbg_priv *priv = netdev_priv(netdev); 148 + 149 + if (pci_enable_device(pdev)) { 150 + dev_err(&pdev->dev, 151 + "failed to re-enable PCI device after reset\n"); 152 + return PCI_ERS_RESULT_DISCONNECT; 153 + } 154 + 155 + pci_set_master(pdev); 156 + pci_restore_state(pdev); 157 + pci_save_state(pdev); 158 + 159 + hbg_err_reset(priv); 160 + netif_device_attach(netdev); 161 + return PCI_ERS_RESULT_RECOVERED; 162 + } 163 + 108 164 static void hbg_pci_err_reset_prepare(struct pci_dev *pdev) 109 165 { 110 166 struct net_device *netdev = pci_get_drvdata(pdev); ··· 180 124 } 181 125 182 126 static const struct pci_error_handlers hbg_pci_err_handler = { 127 + .error_detected = hbg_pci_err_detected, 128 + .slot_reset = hbg_pci_err_slot_reset, 183 129 .reset_prepare = hbg_pci_err_reset_prepare, 184 130 .reset_done = hbg_pci_err_reset_done, 185 131 };
+1
drivers/net/ethernet/hisilicon/hibmcge/hbg_err.h
··· 9 9 void hbg_set_pci_err_handler(struct pci_driver *pdrv); 10 10 int hbg_reset(struct hbg_priv *priv); 11 11 int hbg_rebuild(struct hbg_priv *priv); 12 + void hbg_err_reset(struct hbg_priv *priv); 12 13 13 14 #endif
+298
drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c
··· 9 9 #include "hbg_ethtool.h" 10 10 #include "hbg_hw.h" 11 11 12 + struct hbg_ethtool_stats { 13 + char name[ETH_GSTRING_LEN]; 14 + unsigned long offset; 15 + u32 reg; /* set to 0 if stats is not updated via dump reg */ 16 + }; 17 + 18 + #define HBG_STATS_I(stats) { #stats, HBG_STATS_FIELD_OFF(stats), 0} 19 + #define HBG_STATS_REG_I(stats, reg) { #stats, HBG_STATS_FIELD_OFF(stats), reg} 20 + 21 + static const struct hbg_ethtool_stats hbg_ethtool_stats_info[] = { 22 + HBG_STATS_I(rx_desc_l2_err_cnt), 23 + HBG_STATS_I(rx_desc_pkt_len_err_cnt), 24 + HBG_STATS_I(rx_desc_l3_wrong_head_cnt), 25 + HBG_STATS_I(rx_desc_l3_csum_err_cnt), 26 + HBG_STATS_I(rx_desc_l3_len_err_cnt), 27 + HBG_STATS_I(rx_desc_l3_zero_ttl_cnt), 28 + HBG_STATS_I(rx_desc_l3_other_cnt), 29 + HBG_STATS_I(rx_desc_l4_wrong_head_cnt), 30 + HBG_STATS_I(rx_desc_l4_len_err_cnt), 31 + HBG_STATS_I(rx_desc_l4_csum_err_cnt), 32 + HBG_STATS_I(rx_desc_l4_zero_port_num_cnt), 33 + HBG_STATS_I(rx_desc_l4_other_cnt), 34 + HBG_STATS_I(rx_desc_ip_ver_err_cnt), 35 + HBG_STATS_I(rx_desc_ipv4_pkt_cnt), 36 + HBG_STATS_I(rx_desc_ipv6_pkt_cnt), 37 + HBG_STATS_I(rx_desc_no_ip_pkt_cnt), 38 + HBG_STATS_I(rx_desc_ip_pkt_cnt), 39 + HBG_STATS_I(rx_desc_tcp_pkt_cnt), 40 + HBG_STATS_I(rx_desc_udp_pkt_cnt), 41 + HBG_STATS_I(rx_desc_vlan_pkt_cnt), 42 + HBG_STATS_I(rx_desc_icmp_pkt_cnt), 43 + HBG_STATS_I(rx_desc_arp_pkt_cnt), 44 + HBG_STATS_I(rx_desc_rarp_pkt_cnt), 45 + HBG_STATS_I(rx_desc_multicast_pkt_cnt), 46 + HBG_STATS_I(rx_desc_broadcast_pkt_cnt), 47 + HBG_STATS_I(rx_desc_ipsec_pkt_cnt), 48 + HBG_STATS_I(rx_desc_ip_opt_pkt_cnt), 49 + HBG_STATS_I(rx_desc_key_not_match_cnt), 50 + 51 + HBG_STATS_REG_I(rx_octets_bad_cnt, HBG_REG_RX_OCTETS_BAD_ADDR), 52 + HBG_STATS_REG_I(rx_octets_total_filt_cnt, 53 + HBG_REG_RX_OCTETS_TOTAL_FILT_ADDR), 54 + HBG_STATS_REG_I(rx_uc_pkt_cnt, HBG_REG_RX_UC_PKTS_ADDR), 55 + HBG_STATS_REG_I(rx_vlan_pkt_cnt, HBG_REG_RX_TAGGED_ADDR), 56 + HBG_STATS_REG_I(rx_filt_pkt_cnt, HBG_REG_RX_FILT_PKT_CNT_ADDR), 57 + HBG_STATS_REG_I(rx_data_error_cnt, HBG_REG_RX_DATA_ERR_ADDR), 58 + HBG_STATS_REG_I(rx_frame_long_err_cnt, HBG_REG_RX_LONG_ERRORS_ADDR), 59 + HBG_STATS_REG_I(rx_jabber_err_cnt, HBG_REG_RX_JABBER_ERRORS_ADDR), 60 + HBG_STATS_REG_I(rx_frame_very_long_err_cnt, 61 + HBG_REG_RX_VERY_LONG_ERR_CNT_ADDR), 62 + HBG_STATS_REG_I(rx_frame_runt_err_cnt, HBG_REG_RX_RUNT_ERR_CNT_ADDR), 63 + HBG_STATS_REG_I(rx_frame_short_err_cnt, HBG_REG_RX_SHORT_ERR_CNT_ADDR), 64 + HBG_STATS_REG_I(rx_overflow_cnt, HBG_REG_RX_OVER_FLOW_CNT_ADDR), 65 + HBG_STATS_REG_I(rx_bufrq_err_cnt, HBG_REG_RX_BUFRQ_ERR_CNT_ADDR), 66 + HBG_STATS_REG_I(rx_we_err_cnt, HBG_REG_RX_WE_ERR_CNT_ADDR), 67 + HBG_STATS_REG_I(rx_overrun_cnt, HBG_REG_RX_OVERRUN_CNT_ADDR), 68 + HBG_STATS_REG_I(rx_lengthfield_err_cnt, 69 + HBG_REG_RX_LENGTHFIELD_ERR_CNT_ADDR), 70 + HBG_STATS_REG_I(rx_fail_comma_cnt, HBG_REG_RX_FAIL_COMMA_CNT_ADDR), 71 + HBG_STATS_I(rx_dma_err_cnt), 72 + HBG_STATS_I(rx_fifo_less_empty_thrsld_cnt), 73 + 74 + HBG_STATS_REG_I(tx_uc_pkt_cnt, HBG_REG_TX_UC_PKTS_ADDR), 75 + HBG_STATS_REG_I(tx_vlan_pkt_cnt, HBG_REG_TX_TAGGED_ADDR), 76 + HBG_STATS_REG_I(tx_octets_bad_cnt, HBG_REG_OCTETS_TRANSMITTED_BAD_ADDR), 77 + 78 + HBG_STATS_REG_I(tx_underrun_err_cnt, HBG_REG_TX_UNDERRUN_ADDR), 79 + HBG_STATS_REG_I(tx_add_cs_fail_cnt, HBG_REG_TX_CS_FAIL_CNT_ADDR), 80 + HBG_STATS_REG_I(tx_bufrl_err_cnt, HBG_REG_TX_BUFRL_ERR_CNT_ADDR), 81 + HBG_STATS_REG_I(tx_crc_err_cnt, HBG_REG_TX_CRC_ERROR_ADDR), 82 + HBG_STATS_REG_I(tx_drop_cnt, HBG_REG_TX_DROP_CNT_ADDR), 83 + HBG_STATS_REG_I(tx_excessive_length_drop_cnt, 84 + HBG_REG_TX_EXCESSIVE_LENGTH_DROP_ADDR), 85 + HBG_STATS_I(tx_dma_err_cnt), 86 + HBG_STATS_I(tx_timeout_cnt), 87 + }; 88 + 89 + static const struct hbg_ethtool_stats hbg_ethtool_rmon_stats_info[] = { 90 + HBG_STATS_I(rx_desc_frag_cnt), 91 + HBG_STATS_REG_I(rx_framesize_64, HBG_REG_RX_PKTS_64OCTETS_ADDR), 92 + HBG_STATS_REG_I(rx_framesize_65_127, 93 + HBG_REG_RX_PKTS_65TO127OCTETS_ADDR), 94 + HBG_STATS_REG_I(rx_framesize_128_255, 95 + HBG_REG_RX_PKTS_128TO255OCTETS_ADDR), 96 + HBG_STATS_REG_I(rx_framesize_256_511, 97 + HBG_REG_RX_PKTS_256TO511OCTETS_ADDR), 98 + HBG_STATS_REG_I(rx_framesize_512_1023, 99 + HBG_REG_RX_PKTS_512TO1023OCTETS_ADDR), 100 + HBG_STATS_REG_I(rx_framesize_1024_1518, 101 + HBG_REG_RX_PKTS_1024TO1518OCTETS_ADDR), 102 + HBG_STATS_REG_I(rx_framesize_bt_1518, 103 + HBG_REG_RX_PKTS_1519TOMAXOCTETS_ADDR), 104 + HBG_STATS_REG_I(tx_framesize_64, HBG_REG_TX_PKTS_64OCTETS_ADDR), 105 + HBG_STATS_REG_I(tx_framesize_65_127, 106 + HBG_REG_TX_PKTS_65TO127OCTETS_ADDR), 107 + HBG_STATS_REG_I(tx_framesize_128_255, 108 + HBG_REG_TX_PKTS_128TO255OCTETS_ADDR), 109 + HBG_STATS_REG_I(tx_framesize_256_511, 110 + HBG_REG_TX_PKTS_256TO511OCTETS_ADDR), 111 + HBG_STATS_REG_I(tx_framesize_512_1023, 112 + HBG_REG_TX_PKTS_512TO1023OCTETS_ADDR), 113 + HBG_STATS_REG_I(tx_framesize_1024_1518, 114 + HBG_REG_TX_PKTS_1024TO1518OCTETS_ADDR), 115 + HBG_STATS_REG_I(tx_framesize_bt_1518, 116 + HBG_REG_TX_PKTS_1519TOMAXOCTETS_ADDR), 117 + }; 118 + 119 + static const struct hbg_ethtool_stats hbg_ethtool_mac_stats_info[] = { 120 + HBG_STATS_REG_I(rx_mc_pkt_cnt, HBG_REG_RX_MC_PKTS_ADDR), 121 + HBG_STATS_REG_I(rx_bc_pkt_cnt, HBG_REG_RX_BC_PKTS_ADDR), 122 + HBG_STATS_REG_I(rx_align_error_cnt, HBG_REG_RX_ALIGN_ERRORS_ADDR), 123 + HBG_STATS_REG_I(rx_octets_total_ok_cnt, 124 + HBG_REG_RX_OCTETS_TOTAL_OK_ADDR), 125 + HBG_STATS_REG_I(rx_trans_pkt_cnt, HBG_REG_RX_TRANS_PKG_CNT_ADDR), 126 + HBG_STATS_REG_I(rx_fcs_error_cnt, HBG_REG_RX_FCS_ERRORS_ADDR), 127 + HBG_STATS_REG_I(tx_mc_pkt_cnt, HBG_REG_TX_MC_PKTS_ADDR), 128 + HBG_STATS_REG_I(tx_bc_pkt_cnt, HBG_REG_TX_BC_PKTS_ADDR), 129 + HBG_STATS_REG_I(tx_octets_total_ok_cnt, 130 + HBG_REG_OCTETS_TRANSMITTED_OK_ADDR), 131 + HBG_STATS_REG_I(tx_trans_pkt_cnt, HBG_REG_TX_TRANS_PKG_CNT_ADDR), 132 + }; 133 + 134 + static const struct hbg_ethtool_stats hbg_ethtool_ctrl_stats_info[] = { 135 + HBG_STATS_REG_I(rx_pause_macctl_frame_cnt, 136 + HBG_REG_RX_PAUSE_MACCTL_FRAMCOUNTER_ADDR), 137 + HBG_STATS_REG_I(tx_pause_frame_cnt, HBG_REG_TX_PAUSE_FRAMES_ADDR), 138 + HBG_STATS_REG_I(rx_unknown_macctl_frame_cnt, 139 + HBG_REG_RX_UNKNOWN_MACCTL_FRAMCOUNTER_ADDR), 140 + }; 141 + 12 142 enum hbg_reg_dump_type { 13 143 HBG_DUMP_REG_TYPE_SPEC = 0, 14 144 HBG_DUMP_REG_TYPE_MDIO, ··· 310 180 return hbg_reset(priv); 311 181 } 312 182 183 + static void hbg_update_stats_by_info(struct hbg_priv *priv, 184 + const struct hbg_ethtool_stats *info, 185 + u32 info_len) 186 + { 187 + const struct hbg_ethtool_stats *stats; 188 + u32 i; 189 + 190 + for (i = 0; i < info_len; i++) { 191 + stats = &info[i]; 192 + if (!stats->reg) 193 + continue; 194 + 195 + HBG_STATS_U(&priv->stats, stats->offset, 196 + hbg_reg_read(priv, stats->reg)); 197 + } 198 + } 199 + 200 + void hbg_update_stats(struct hbg_priv *priv) 201 + { 202 + hbg_update_stats_by_info(priv, hbg_ethtool_stats_info, 203 + ARRAY_SIZE(hbg_ethtool_stats_info)); 204 + hbg_update_stats_by_info(priv, hbg_ethtool_rmon_stats_info, 205 + ARRAY_SIZE(hbg_ethtool_rmon_stats_info)); 206 + hbg_update_stats_by_info(priv, hbg_ethtool_mac_stats_info, 207 + ARRAY_SIZE(hbg_ethtool_mac_stats_info)); 208 + hbg_update_stats_by_info(priv, hbg_ethtool_ctrl_stats_info, 209 + ARRAY_SIZE(hbg_ethtool_ctrl_stats_info)); 210 + } 211 + 212 + static int hbg_ethtool_get_sset_count(struct net_device *netdev, int stringset) 213 + { 214 + if (stringset != ETH_SS_STATS) 215 + return -EOPNOTSUPP; 216 + 217 + return ARRAY_SIZE(hbg_ethtool_stats_info); 218 + } 219 + 220 + static void hbg_ethtool_get_strings(struct net_device *netdev, 221 + u32 stringset, u8 *data) 222 + { 223 + u32 i; 224 + 225 + if (stringset != ETH_SS_STATS) 226 + return; 227 + 228 + for (i = 0; i < ARRAY_SIZE(hbg_ethtool_stats_info); i++) 229 + ethtool_puts(&data, hbg_ethtool_stats_info[i].name); 230 + } 231 + 232 + static void hbg_ethtool_get_stats(struct net_device *netdev, 233 + struct ethtool_stats *stats, u64 *data) 234 + { 235 + struct hbg_priv *priv = netdev_priv(netdev); 236 + u32 i; 237 + 238 + hbg_update_stats(priv); 239 + for (i = 0; i < ARRAY_SIZE(hbg_ethtool_stats_info); i++) 240 + *data++ = HBG_STATS_R(&priv->stats, 241 + hbg_ethtool_stats_info[i].offset); 242 + } 243 + 244 + static void hbg_ethtool_get_pause_stats(struct net_device *netdev, 245 + struct ethtool_pause_stats *epstats) 246 + { 247 + struct hbg_priv *priv = netdev_priv(netdev); 248 + struct hbg_stats *stats = &priv->stats; 249 + 250 + hbg_update_stats(priv); 251 + epstats->rx_pause_frames = stats->rx_pause_macctl_frame_cnt; 252 + epstats->tx_pause_frames = stats->tx_pause_frame_cnt; 253 + } 254 + 255 + static void hbg_ethtool_get_eth_mac_stats(struct net_device *netdev, 256 + struct ethtool_eth_mac_stats *emstats) 257 + { 258 + struct hbg_priv *priv = netdev_priv(netdev); 259 + struct hbg_stats *stats = &priv->stats; 260 + 261 + hbg_update_stats(priv); 262 + emstats->FramesTransmittedOK = stats->tx_trans_pkt_cnt; 263 + emstats->FramesReceivedOK = stats->rx_trans_pkt_cnt; 264 + emstats->FrameCheckSequenceErrors = stats->rx_fcs_error_cnt; 265 + emstats->AlignmentErrors = stats->rx_align_error_cnt; 266 + emstats->OctetsTransmittedOK = stats->tx_octets_total_ok_cnt; 267 + emstats->OctetsReceivedOK = stats->rx_octets_total_ok_cnt; 268 + 269 + emstats->MulticastFramesXmittedOK = stats->tx_mc_pkt_cnt; 270 + emstats->BroadcastFramesXmittedOK = stats->tx_bc_pkt_cnt; 271 + emstats->MulticastFramesReceivedOK = stats->rx_mc_pkt_cnt; 272 + emstats->BroadcastFramesReceivedOK = stats->rx_bc_pkt_cnt; 273 + emstats->InRangeLengthErrors = stats->rx_fcs_error_cnt + 274 + stats->rx_jabber_err_cnt + 275 + stats->rx_unknown_macctl_frame_cnt + 276 + stats->rx_bufrq_err_cnt + 277 + stats->rx_we_err_cnt; 278 + emstats->OutOfRangeLengthField = stats->rx_frame_short_err_cnt + 279 + stats->rx_frame_runt_err_cnt + 280 + stats->rx_lengthfield_err_cnt + 281 + stats->rx_frame_long_err_cnt + 282 + stats->rx_frame_very_long_err_cnt; 283 + emstats->FrameTooLongErrors = stats->rx_frame_long_err_cnt + 284 + stats->rx_frame_very_long_err_cnt; 285 + } 286 + 287 + static void 288 + hbg_ethtool_get_eth_ctrl_stats(struct net_device *netdev, 289 + struct ethtool_eth_ctrl_stats *ecstats) 290 + { 291 + struct hbg_priv *priv = netdev_priv(netdev); 292 + struct hbg_stats *s = &priv->stats; 293 + 294 + hbg_update_stats(priv); 295 + ecstats->MACControlFramesTransmitted = s->tx_pause_frame_cnt; 296 + ecstats->MACControlFramesReceived = s->rx_pause_macctl_frame_cnt; 297 + ecstats->UnsupportedOpcodesReceived = s->rx_unknown_macctl_frame_cnt; 298 + } 299 + 300 + static const struct ethtool_rmon_hist_range hbg_rmon_ranges[] = { 301 + { 0, 64 }, 302 + { 65, 127 }, 303 + { 128, 255 }, 304 + { 256, 511 }, 305 + { 512, 1023 }, 306 + { 1024, 1518 }, 307 + { 1519, 4095 }, 308 + }; 309 + 310 + static void 311 + hbg_ethtool_get_rmon_stats(struct net_device *netdev, 312 + struct ethtool_rmon_stats *rmon_stats, 313 + const struct ethtool_rmon_hist_range **ranges) 314 + { 315 + struct hbg_priv *priv = netdev_priv(netdev); 316 + struct hbg_stats *stats = &priv->stats; 317 + 318 + hbg_update_stats(priv); 319 + rmon_stats->undersize_pkts = stats->rx_frame_short_err_cnt + 320 + stats->rx_frame_runt_err_cnt + 321 + stats->rx_lengthfield_err_cnt; 322 + rmon_stats->oversize_pkts = stats->rx_frame_long_err_cnt + 323 + stats->rx_frame_very_long_err_cnt; 324 + rmon_stats->fragments = stats->rx_desc_frag_cnt; 325 + rmon_stats->hist[0] = stats->rx_framesize_64; 326 + rmon_stats->hist[1] = stats->rx_framesize_65_127; 327 + rmon_stats->hist[2] = stats->rx_framesize_128_255; 328 + rmon_stats->hist[3] = stats->rx_framesize_256_511; 329 + rmon_stats->hist[4] = stats->rx_framesize_512_1023; 330 + rmon_stats->hist[5] = stats->rx_framesize_1024_1518; 331 + rmon_stats->hist[6] = stats->rx_framesize_bt_1518; 332 + 333 + rmon_stats->hist_tx[0] = stats->tx_framesize_64; 334 + rmon_stats->hist_tx[1] = stats->tx_framesize_65_127; 335 + rmon_stats->hist_tx[2] = stats->tx_framesize_128_255; 336 + rmon_stats->hist_tx[3] = stats->tx_framesize_256_511; 337 + rmon_stats->hist_tx[4] = stats->tx_framesize_512_1023; 338 + rmon_stats->hist_tx[5] = stats->tx_framesize_1024_1518; 339 + rmon_stats->hist_tx[6] = stats->tx_framesize_bt_1518; 340 + 341 + *ranges = hbg_rmon_ranges; 342 + } 343 + 313 344 static const struct ethtool_ops hbg_ethtool_ops = { 314 345 .get_link = ethtool_op_get_link, 315 346 .get_link_ksettings = phy_ethtool_get_link_ksettings, ··· 481 190 .set_pauseparam = hbg_ethtool_set_pauseparam, 482 191 .reset = hbg_ethtool_reset, 483 192 .nway_reset = phy_ethtool_nway_reset, 193 + .get_sset_count = hbg_ethtool_get_sset_count, 194 + .get_strings = hbg_ethtool_get_strings, 195 + .get_ethtool_stats = hbg_ethtool_get_stats, 196 + .get_pause_stats = hbg_ethtool_get_pause_stats, 197 + .get_eth_mac_stats = hbg_ethtool_get_eth_mac_stats, 198 + .get_eth_ctrl_stats = hbg_ethtool_get_eth_ctrl_stats, 199 + .get_rmon_stats = hbg_ethtool_get_rmon_stats, 484 200 }; 485 201 486 202 void hbg_ethtool_set_ops(struct net_device *netdev)
+5
drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.h
··· 6 6 7 7 #include <linux/netdevice.h> 8 8 9 + #define HBG_STATS_FIELD_OFF(f) (offsetof(struct hbg_stats, f)) 10 + #define HBG_STATS_R(p, offset) (*(u64 *)((u8 *)(p) + (offset))) 11 + #define HBG_STATS_U(p, offset, val) (HBG_STATS_R(p, offset) += (val)) 12 + 9 13 void hbg_ethtool_set_ops(struct net_device *netdev); 14 + void hbg_update_stats(struct hbg_priv *priv); 10 15 11 16 #endif
+10
drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c
··· 213 213 214 214 void hbg_hw_adjust_link(struct hbg_priv *priv, u32 speed, u32 duplex) 215 215 { 216 + hbg_hw_mac_enable(priv, HBG_STATUS_DISABLE); 217 + 216 218 hbg_reg_write_field(priv, HBG_REG_PORT_MODE_ADDR, 217 219 HBG_REG_PORT_MODE_M, speed); 218 220 hbg_reg_write_field(priv, HBG_REG_DUPLEX_TYPE_ADDR, 219 221 HBG_REG_DUPLEX_B, duplex); 222 + 223 + hbg_hw_event_notify(priv, HBG_HW_EVENT_CORE_RESET); 224 + 225 + hbg_hw_mac_enable(priv, HBG_STATUS_ENABLE); 226 + 227 + if (!hbg_reg_read_field(priv, HBG_REG_AN_NEG_STATE_ADDR, 228 + HBG_REG_AN_NEG_STATE_NP_LINK_OK_B)) 229 + hbg_np_link_fail_task_schedule(priv); 220 230 } 221 231 222 232 /* only support uc filter */
+33 -22
drivers/net/ethernet/hisilicon/hibmcge/hbg_irq.c
··· 11 11 if (irq_info->need_print) 12 12 dev_err(&priv->pdev->dev, 13 13 "receive error interrupt: %s\n", irq_info->name); 14 + 15 + if (irq_info->need_reset) 16 + hbg_err_reset_task_schedule(priv); 14 17 } 15 18 16 19 static void hbg_irq_handle_tx(struct hbg_priv *priv, ··· 28 25 napi_schedule(&priv->rx_ring.napi); 29 26 } 30 27 31 - #define HBG_TXRX_IRQ_I(name, handle) \ 32 - {#name, HBG_INT_MSK_##name##_B, false, false, 0, handle} 33 - #define HBG_ERR_IRQ_I(name, need_print) \ 34 - {#name, HBG_INT_MSK_##name##_B, true, need_print, 0, hbg_irq_handle_err} 28 + static void hbg_irq_handle_rx_buf_val(struct hbg_priv *priv, 29 + struct hbg_irq_info *irq_info) 30 + { 31 + priv->stats.rx_fifo_less_empty_thrsld_cnt++; 32 + } 33 + 34 + #define HBG_IRQ_I(name, handle) \ 35 + {#name, HBG_INT_MSK_##name##_B, false, false, false, 0, handle} 36 + #define HBG_ERR_IRQ_I(name, need_print, ndde_reset) \ 37 + {#name, HBG_INT_MSK_##name##_B, true, need_print, \ 38 + ndde_reset, 0, hbg_irq_handle_err} 35 39 36 40 static struct hbg_irq_info hbg_irqs[] = { 37 - HBG_TXRX_IRQ_I(RX, hbg_irq_handle_rx), 38 - HBG_TXRX_IRQ_I(TX, hbg_irq_handle_tx), 39 - HBG_ERR_IRQ_I(MAC_MII_FIFO_ERR, true), 40 - HBG_ERR_IRQ_I(MAC_PCS_RX_FIFO_ERR, true), 41 - HBG_ERR_IRQ_I(MAC_PCS_TX_FIFO_ERR, true), 42 - HBG_ERR_IRQ_I(MAC_APP_RX_FIFO_ERR, true), 43 - HBG_ERR_IRQ_I(MAC_APP_TX_FIFO_ERR, true), 44 - HBG_ERR_IRQ_I(SRAM_PARITY_ERR, true), 45 - HBG_ERR_IRQ_I(TX_AHB_ERR, true), 46 - HBG_ERR_IRQ_I(RX_BUF_AVL, false), 47 - HBG_ERR_IRQ_I(REL_BUF_ERR, true), 48 - HBG_ERR_IRQ_I(TXCFG_AVL, false), 49 - HBG_ERR_IRQ_I(TX_DROP, false), 50 - HBG_ERR_IRQ_I(RX_DROP, false), 51 - HBG_ERR_IRQ_I(RX_AHB_ERR, true), 52 - HBG_ERR_IRQ_I(MAC_FIFO_ERR, false), 53 - HBG_ERR_IRQ_I(RBREQ_ERR, false), 54 - HBG_ERR_IRQ_I(WE_ERR, false), 41 + HBG_IRQ_I(RX, hbg_irq_handle_rx), 42 + HBG_IRQ_I(TX, hbg_irq_handle_tx), 43 + HBG_ERR_IRQ_I(TX_PKT_CPL, true, true), 44 + HBG_ERR_IRQ_I(MAC_MII_FIFO_ERR, true, true), 45 + HBG_ERR_IRQ_I(MAC_PCS_RX_FIFO_ERR, true, true), 46 + HBG_ERR_IRQ_I(MAC_PCS_TX_FIFO_ERR, true, true), 47 + HBG_ERR_IRQ_I(MAC_APP_RX_FIFO_ERR, true, true), 48 + HBG_ERR_IRQ_I(MAC_APP_TX_FIFO_ERR, true, true), 49 + HBG_ERR_IRQ_I(SRAM_PARITY_ERR, true, false), 50 + HBG_ERR_IRQ_I(TX_AHB_ERR, true, true), 51 + HBG_IRQ_I(RX_BUF_AVL, hbg_irq_handle_rx_buf_val), 52 + HBG_ERR_IRQ_I(REL_BUF_ERR, true, false), 53 + HBG_ERR_IRQ_I(TXCFG_AVL, false, false), 54 + HBG_ERR_IRQ_I(TX_DROP, false, false), 55 + HBG_ERR_IRQ_I(RX_DROP, false, false), 56 + HBG_ERR_IRQ_I(RX_AHB_ERR, true, false), 57 + HBG_ERR_IRQ_I(MAC_FIFO_ERR, true, true), 58 + HBG_ERR_IRQ_I(RBREQ_ERR, true, true), 59 + HBG_ERR_IRQ_I(WE_ERR, true, true), 55 60 }; 56 61 57 62 static irqreturn_t hbg_irq_handle(int irq_num, void *p)
+103
drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
··· 5 5 #include <linux/if_vlan.h> 6 6 #include <linux/netdevice.h> 7 7 #include <linux/pci.h> 8 + #include <linux/phy.h> 8 9 #include "hbg_common.h" 10 + #include "hbg_diagnose.h" 9 11 #include "hbg_err.h" 10 12 #include "hbg_ethtool.h" 11 13 #include "hbg_hw.h" ··· 15 13 #include "hbg_mdio.h" 16 14 #include "hbg_txrx.h" 17 15 #include "hbg_debugfs.h" 16 + 17 + #define HBG_SUPPORT_FEATURES (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \ 18 + NETIF_F_RXCSUM) 18 19 19 20 static void hbg_all_irq_enable(struct hbg_priv *priv, bool enabled) 20 21 { ··· 219 214 char *buf = ring->tout_log_buf; 220 215 u32 pos = 0; 221 216 217 + priv->stats.tx_timeout_cnt++; 218 + 219 + pos += scnprintf(buf + pos, HBG_TX_TIMEOUT_BUF_LEN - pos, 220 + "tx_timeout cnt: %llu\n", priv->stats.tx_timeout_cnt); 222 221 pos += scnprintf(buf + pos, HBG_TX_TIMEOUT_BUF_LEN - pos, 223 222 "ring used num: %u, fifo used num: %u\n", 224 223 hbg_get_queue_used_num(ring), ··· 235 226 netdev_info(netdev, "%s", buf); 236 227 } 237 228 229 + static void hbg_net_get_stats(struct net_device *netdev, 230 + struct rtnl_link_stats64 *stats) 231 + { 232 + struct hbg_priv *priv = netdev_priv(netdev); 233 + struct hbg_stats *h_stats = &priv->stats; 234 + 235 + hbg_update_stats(priv); 236 + dev_get_tstats64(netdev, stats); 237 + 238 + /* fifo empty */ 239 + stats->tx_fifo_errors += h_stats->tx_drop_cnt; 240 + 241 + stats->tx_dropped += h_stats->tx_excessive_length_drop_cnt + 242 + h_stats->tx_drop_cnt; 243 + stats->tx_errors += h_stats->tx_add_cs_fail_cnt + 244 + h_stats->tx_bufrl_err_cnt + 245 + h_stats->tx_underrun_err_cnt + 246 + h_stats->tx_crc_err_cnt; 247 + stats->rx_errors += h_stats->rx_data_error_cnt; 248 + stats->multicast += h_stats->rx_mc_pkt_cnt; 249 + stats->rx_dropped += h_stats->rx_desc_drop; 250 + stats->rx_length_errors += h_stats->rx_frame_very_long_err_cnt + 251 + h_stats->rx_frame_long_err_cnt + 252 + h_stats->rx_frame_runt_err_cnt + 253 + h_stats->rx_frame_short_err_cnt + 254 + h_stats->rx_lengthfield_err_cnt; 255 + stats->rx_frame_errors += h_stats->rx_desc_l2_err_cnt + 256 + h_stats->rx_desc_l3l4_err_cnt; 257 + stats->rx_fifo_errors += h_stats->rx_overflow_cnt + 258 + h_stats->rx_overrun_cnt; 259 + stats->rx_crc_errors += h_stats->rx_fcs_error_cnt; 260 + } 261 + 238 262 static const struct net_device_ops hbg_netdev_ops = { 239 263 .ndo_open = hbg_net_open, 240 264 .ndo_stop = hbg_net_stop, ··· 277 235 .ndo_change_mtu = hbg_net_change_mtu, 278 236 .ndo_tx_timeout = hbg_net_tx_timeout, 279 237 .ndo_set_rx_mode = hbg_net_set_rx_mode, 238 + .ndo_get_stats64 = hbg_net_get_stats, 239 + .ndo_eth_ioctl = phy_do_ioctl_running, 280 240 }; 241 + 242 + static void hbg_service_task(struct work_struct *work) 243 + { 244 + struct hbg_priv *priv = container_of(work, struct hbg_priv, 245 + service_task.work); 246 + 247 + if (test_and_clear_bit(HBG_NIC_STATE_NEED_RESET, &priv->state)) 248 + hbg_err_reset(priv); 249 + 250 + if (test_and_clear_bit(HBG_NIC_STATE_NP_LINK_FAIL, &priv->state)) 251 + hbg_fix_np_link_fail(priv); 252 + 253 + hbg_diagnose_message_push(priv); 254 + 255 + /* The type of statistics register is u32, 256 + * To prevent the statistics register from overflowing, 257 + * the driver dumps the statistics every 30 seconds. 258 + */ 259 + if (time_after(jiffies, priv->last_update_stats_time + 30 * HZ)) { 260 + hbg_update_stats(priv); 261 + priv->last_update_stats_time = jiffies; 262 + } 263 + 264 + schedule_delayed_work(&priv->service_task, 265 + msecs_to_jiffies(MSEC_PER_SEC)); 266 + } 267 + 268 + void hbg_err_reset_task_schedule(struct hbg_priv *priv) 269 + { 270 + set_bit(HBG_NIC_STATE_NEED_RESET, &priv->state); 271 + schedule_delayed_work(&priv->service_task, 0); 272 + } 273 + 274 + void hbg_np_link_fail_task_schedule(struct hbg_priv *priv) 275 + { 276 + set_bit(HBG_NIC_STATE_NP_LINK_FAIL, &priv->state); 277 + schedule_delayed_work(&priv->service_task, 0); 278 + } 279 + 280 + static void hbg_cancel_delayed_work_sync(void *data) 281 + { 282 + cancel_delayed_work_sync(data); 283 + } 284 + 285 + static int hbg_delaywork_init(struct hbg_priv *priv) 286 + { 287 + INIT_DELAYED_WORK(&priv->service_task, hbg_service_task); 288 + schedule_delayed_work(&priv->service_task, 0); 289 + return devm_add_action_or_reset(&priv->pdev->dev, 290 + hbg_cancel_delayed_work_sync, 291 + &priv->service_task); 292 + } 281 293 282 294 static int hbg_mac_filter_init(struct hbg_priv *priv) 283 295 { ··· 384 288 return ret; 385 289 386 290 ret = hbg_mac_filter_init(priv); 291 + if (ret) 292 + return ret; 293 + 294 + ret = hbg_delaywork_init(priv); 387 295 if (ret) 388 296 return ret; 389 297 ··· 449 349 if (ret) 450 350 return ret; 451 351 352 + /* set default features */ 353 + netdev->features |= HBG_SUPPORT_FEATURES; 354 + netdev->hw_features |= HBG_SUPPORT_FEATURES; 452 355 netdev->priv_flags |= IFF_UNICAST_FLT; 453 356 454 357 netdev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
+22
drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c
··· 17 17 #define HBG_MDIO_OP_TIMEOUT_US (1 * 1000 * 1000) 18 18 #define HBG_MDIO_OP_INTERVAL_US (5 * 1000) 19 19 20 + #define HBG_NP_LINK_FAIL_RETRY_TIMES 5 21 + 20 22 static void hbg_mdio_set_command(struct hbg_mac *mac, u32 cmd) 21 23 { 22 24 hbg_reg_write(HBG_MAC_GET_PRIV(mac), HBG_REG_MDIO_COMMAND_ADDR, cmd); ··· 127 125 128 126 phy_get_pause(phydev, &tx_pause, &rx_pause); 129 127 hbg_hw_set_pause_enable(priv, tx_pause, rx_pause); 128 + } 129 + 130 + void hbg_fix_np_link_fail(struct hbg_priv *priv) 131 + { 132 + struct device *dev = &priv->pdev->dev; 133 + 134 + if (priv->stats.np_link_fail_cnt >= HBG_NP_LINK_FAIL_RETRY_TIMES) { 135 + dev_err(dev, "failed to fix the MAC link status\n"); 136 + priv->stats.np_link_fail_cnt = 0; 137 + return; 138 + } 139 + 140 + priv->stats.np_link_fail_cnt++; 141 + dev_err(dev, "failed to link between MAC and PHY, try to fix...\n"); 142 + 143 + /* Replace phy_reset() with phy_stop() and phy_start(), 144 + * as suggested by Andrew. 145 + */ 146 + hbg_phy_stop(priv); 147 + hbg_phy_start(priv); 130 148 } 131 149 132 150 static void hbg_phy_adjust_link(struct net_device *netdev)
+2
drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.h
··· 9 9 int hbg_mdio_init(struct hbg_priv *priv); 10 10 void hbg_phy_start(struct hbg_priv *priv); 11 11 void hbg_phy_stop(struct hbg_priv *priv); 12 + void hbg_fix_np_link_fail(struct hbg_priv *priv); 13 + 12 14 #endif
+105
drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h
··· 18 18 #define HBG_REG_TX_FIFO_NUM_ADDR 0x0030 19 19 #define HBG_REG_RX_FIFO_NUM_ADDR 0x0034 20 20 #define HBG_REG_VLAN_LAYERS_ADDR 0x0038 21 + #define HBG_REG_PUSH_REQ_ADDR 0x00F0 22 + #define HBG_REG_MSG_HEADER_ADDR 0x00F4 23 + #define HBG_REG_MSG_HEADER_OPCODE_M GENMASK(7, 0) 24 + #define HBG_REG_MSG_HEADER_STATUS_M GENMASK(11, 8) 25 + #define HBG_REG_MSG_HEADER_DATA_NUM_M GENMASK(19, 12) 26 + #define HBG_REG_MSG_HEADER_RESP_CODE_M GENMASK(27, 20) 27 + #define HBG_REG_MSG_DATA_BASE_ADDR 0x0100 21 28 22 29 /* MDIO */ 23 30 #define HBG_REG_MDIO_BASE 0x8000 ··· 61 54 #define HBG_REG_PAUSE_ENABLE_RX_B BIT(0) 62 55 #define HBG_REG_PAUSE_ENABLE_TX_B BIT(1) 63 56 #define HBG_REG_AN_NEG_STATE_ADDR (HBG_REG_SGMII_BASE + 0x0058) 57 + #define HBG_REG_AN_NEG_STATE_NP_LINK_OK_B BIT(15) 64 58 #define HBG_REG_TRANSMIT_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x0060) 65 59 #define HBG_REG_TRANSMIT_CTRL_PAD_EN_B BIT(7) 66 60 #define HBG_REG_TRANSMIT_CTRL_CRC_ADD_B BIT(6) 67 61 #define HBG_REG_TRANSMIT_CTRL_AN_EN_B BIT(5) 68 62 #define HBG_REG_REC_FILT_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x0064) 69 63 #define HBG_REG_REC_FILT_CTRL_UC_MATCH_EN_B BIT(0) 64 + #define HBG_REG_RX_OCTETS_TOTAL_OK_ADDR (HBG_REG_SGMII_BASE + 0x0080) 65 + #define HBG_REG_RX_OCTETS_BAD_ADDR (HBG_REG_SGMII_BASE + 0x0084) 66 + #define HBG_REG_RX_UC_PKTS_ADDR (HBG_REG_SGMII_BASE + 0x0088) 67 + #define HBG_REG_RX_MC_PKTS_ADDR (HBG_REG_SGMII_BASE + 0x008C) 68 + #define HBG_REG_RX_BC_PKTS_ADDR (HBG_REG_SGMII_BASE + 0x0090) 69 + #define HBG_REG_RX_PKTS_64OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x0094) 70 + #define HBG_REG_RX_PKTS_65TO127OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x0098) 71 + #define HBG_REG_RX_PKTS_128TO255OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x009C) 72 + #define HBG_REG_RX_PKTS_256TO511OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x00A0) 73 + #define HBG_REG_RX_PKTS_512TO1023OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x00A4) 74 + #define HBG_REG_RX_PKTS_1024TO1518OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x00A8) 75 + #define HBG_REG_RX_PKTS_1519TOMAXOCTETS_ADDR (HBG_REG_SGMII_BASE + 0x00AC) 76 + #define HBG_REG_RX_FCS_ERRORS_ADDR (HBG_REG_SGMII_BASE + 0x00B0) 77 + #define HBG_REG_RX_TAGGED_ADDR (HBG_REG_SGMII_BASE + 0x00B4) 78 + #define HBG_REG_RX_DATA_ERR_ADDR (HBG_REG_SGMII_BASE + 0x00B8) 79 + #define HBG_REG_RX_ALIGN_ERRORS_ADDR (HBG_REG_SGMII_BASE + 0x00BC) 80 + #define HBG_REG_RX_LONG_ERRORS_ADDR (HBG_REG_SGMII_BASE + 0x00C0) 81 + #define HBG_REG_RX_JABBER_ERRORS_ADDR (HBG_REG_SGMII_BASE + 0x00C4) 82 + #define HBG_REG_RX_PAUSE_MACCTL_FRAMCOUNTER_ADDR (HBG_REG_SGMII_BASE + 0x00C8) 83 + #define HBG_REG_RX_UNKNOWN_MACCTL_FRAMCOUNTER_ADDR (HBG_REG_SGMII_BASE + 0x00CC) 84 + #define HBG_REG_RX_VERY_LONG_ERR_CNT_ADDR (HBG_REG_SGMII_BASE + 0x00D0) 85 + #define HBG_REG_RX_RUNT_ERR_CNT_ADDR (HBG_REG_SGMII_BASE + 0x00D4) 86 + #define HBG_REG_RX_SHORT_ERR_CNT_ADDR (HBG_REG_SGMII_BASE + 0x00D8) 87 + #define HBG_REG_RX_FILT_PKT_CNT_ADDR (HBG_REG_SGMII_BASE + 0x00E8) 88 + #define HBG_REG_RX_OCTETS_TOTAL_FILT_ADDR (HBG_REG_SGMII_BASE + 0x00EC) 89 + #define HBG_REG_OCTETS_TRANSMITTED_OK_ADDR (HBG_REG_SGMII_BASE + 0x0100) 90 + #define HBG_REG_OCTETS_TRANSMITTED_BAD_ADDR (HBG_REG_SGMII_BASE + 0x0104) 91 + #define HBG_REG_TX_UC_PKTS_ADDR (HBG_REG_SGMII_BASE + 0x0108) 92 + #define HBG_REG_TX_MC_PKTS_ADDR (HBG_REG_SGMII_BASE + 0x010C) 93 + #define HBG_REG_TX_BC_PKTS_ADDR (HBG_REG_SGMII_BASE + 0x0110) 94 + #define HBG_REG_TX_PKTS_64OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x0114) 95 + #define HBG_REG_TX_PKTS_65TO127OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x0118) 96 + #define HBG_REG_TX_PKTS_128TO255OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x011C) 97 + #define HBG_REG_TX_PKTS_256TO511OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x0120) 98 + #define HBG_REG_TX_PKTS_512TO1023OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x0124) 99 + #define HBG_REG_TX_PKTS_1024TO1518OCTETS_ADDR (HBG_REG_SGMII_BASE + 0x0128) 100 + #define HBG_REG_TX_PKTS_1519TOMAXOCTETS_ADDR (HBG_REG_SGMII_BASE + 0x012C) 101 + #define HBG_REG_TX_EXCESSIVE_LENGTH_DROP_ADDR (HBG_REG_SGMII_BASE + 0x014C) 102 + #define HBG_REG_TX_UNDERRUN_ADDR (HBG_REG_SGMII_BASE + 0x0150) 103 + #define HBG_REG_TX_TAGGED_ADDR (HBG_REG_SGMII_BASE + 0x0154) 104 + #define HBG_REG_TX_CRC_ERROR_ADDR (HBG_REG_SGMII_BASE + 0x0158) 105 + #define HBG_REG_TX_PAUSE_FRAMES_ADDR (HBG_REG_SGMII_BASE + 0x015C) 70 106 #define HBG_REG_LINE_LOOP_BACK_ADDR (HBG_REG_SGMII_BASE + 0x01A8) 71 107 #define HBG_REG_CF_CRC_STRIP_ADDR (HBG_REG_SGMII_BASE + 0x01B0) 72 108 #define HBG_REG_CF_CRC_STRIP_B BIT(0) ··· 119 69 #define HBG_REG_RECV_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x01E0) 120 70 #define HBG_REG_RECV_CTRL_STRIP_PAD_EN_B BIT(3) 121 71 #define HBG_REG_VLAN_CODE_ADDR (HBG_REG_SGMII_BASE + 0x01E8) 72 + #define HBG_REG_RX_OVERRUN_CNT_ADDR (HBG_REG_SGMII_BASE + 0x01EC) 73 + #define HBG_REG_RX_LENGTHFIELD_ERR_CNT_ADDR (HBG_REG_SGMII_BASE + 0x01F4) 74 + #define HBG_REG_RX_FAIL_COMMA_CNT_ADDR (HBG_REG_SGMII_BASE + 0x01F8) 122 75 #define HBG_REG_STATION_ADDR_LOW_0_ADDR (HBG_REG_SGMII_BASE + 0x0200) 123 76 #define HBG_REG_STATION_ADDR_HIGH_0_ADDR (HBG_REG_SGMII_BASE + 0x0204) 124 77 #define HBG_REG_STATION_ADDR_LOW_1_ADDR (HBG_REG_SGMII_BASE + 0x0208) ··· 156 103 #define HBG_INT_MSK_MAC_PCS_TX_FIFO_ERR_B BIT(17) 157 104 #define HBG_INT_MSK_MAC_PCS_RX_FIFO_ERR_B BIT(16) 158 105 #define HBG_INT_MSK_MAC_MII_FIFO_ERR_B BIT(15) 106 + #define HBG_INT_MSK_TX_PKT_CPL_B BIT(14) 159 107 #define HBG_INT_MSK_TX_B BIT(1) /* just used in driver */ 160 108 #define HBG_INT_MSK_RX_B BIT(0) /* just used in driver */ 161 109 #define HBG_REG_CF_INTRPT_STAT_ADDR (HBG_REG_SGMII_BASE + 0x0434) ··· 165 111 #define HBG_REG_RX_BUS_ERR_ADDR_ADDR (HBG_REG_SGMII_BASE + 0x0440) 166 112 #define HBG_REG_MAX_FRAME_LEN_ADDR (HBG_REG_SGMII_BASE + 0x0444) 167 113 #define HBG_REG_MAX_FRAME_LEN_M GENMASK(15, 0) 114 + #define HBG_REG_TX_DROP_CNT_ADDR (HBG_REG_SGMII_BASE + 0x0448) 115 + #define HBG_REG_RX_OVER_FLOW_CNT_ADDR (HBG_REG_SGMII_BASE + 0x044C) 168 116 #define HBG_REG_DEBUG_ST_MCH_ADDR (HBG_REG_SGMII_BASE + 0x0450) 169 117 #define HBG_REG_FIFO_CURR_STATUS_ADDR (HBG_REG_SGMII_BASE + 0x0454) 170 118 #define HBG_REG_FIFO_HIST_STATUS_ADDR (HBG_REG_SGMII_BASE + 0x0458) 171 119 #define HBG_REG_CF_CFF_DATA_NUM_ADDR (HBG_REG_SGMII_BASE + 0x045C) 172 120 #define HBG_REG_CF_CFF_DATA_NUM_ADDR_TX_M GENMASK(8, 0) 173 121 #define HBG_REG_CF_CFF_DATA_NUM_ADDR_RX_M GENMASK(24, 16) 122 + #define HBG_REG_TX_CS_FAIL_CNT_ADDR (HBG_REG_SGMII_BASE + 0x0460) 123 + #define HBG_REG_RX_TRANS_PKG_CNT_ADDR (HBG_REG_SGMII_BASE + 0x0464) 124 + #define HBG_REG_TX_TRANS_PKG_CNT_ADDR (HBG_REG_SGMII_BASE + 0x0468) 174 125 #define HBG_REG_CF_TX_PAUSE_ADDR (HBG_REG_SGMII_BASE + 0x0470) 175 126 #define HBG_REG_TX_CFF_ADDR_0_ADDR (HBG_REG_SGMII_BASE + 0x0488) 176 127 #define HBG_REG_TX_CFF_ADDR_1_ADDR (HBG_REG_SGMII_BASE + 0x048C) ··· 195 136 #define HBG_REG_RX_CTRL_RXBUF_1ST_SKIP_SIZE2_M GENMASK(3, 0) 196 137 #define HBG_REG_RX_PKT_MODE_ADDR (HBG_REG_SGMII_BASE + 0x04F4) 197 138 #define HBG_REG_RX_PKT_MODE_PARSE_MODE_M GENMASK(22, 21) 139 + #define HBG_REG_RX_BUFRQ_ERR_CNT_ADDR (HBG_REG_SGMII_BASE + 0x058C) 140 + #define HBG_REG_TX_BUFRL_ERR_CNT_ADDR (HBG_REG_SGMII_BASE + 0x0590) 141 + #define HBG_REG_RX_WE_ERR_CNT_ADDR (HBG_REG_SGMII_BASE + 0x0594) 198 142 #define HBG_REG_DBG_ST0_ADDR (HBG_REG_SGMII_BASE + 0x05E4) 199 143 #define HBG_REG_DBG_ST1_ADDR (HBG_REG_SGMII_BASE + 0x05E8) 200 144 #define HBG_REG_DBG_ST2_ADDR (HBG_REG_SGMII_BASE + 0x05EC) ··· 240 178 }; 241 179 242 180 #define HBG_RX_DESC_W2_PKT_LEN_M GENMASK(31, 16) 181 + #define HBG_RX_DESC_W2_PORT_NUM_M GENMASK(15, 12) 182 + #define HBG_RX_DESC_W4_IP_TCP_UDP_M GENMASK(31, 30) 183 + #define HBG_RX_DESC_W4_IPSEC_B BIT(29) 184 + #define HBG_RX_DESC_W4_IP_VERSION_B BIT(28) 185 + #define HBG_RX_DESC_W4_L4_ERR_CODE_M GENMASK(26, 23) 186 + #define HBG_RX_DESC_W4_FRAG_B BIT(22) 187 + #define HBG_RX_DESC_W4_OPT_B BIT(21) 188 + #define HBG_RX_DESC_W4_IP_VERSION_ERR_B BIT(20) 189 + #define HBG_RX_DESC_W4_BRD_CST_B BIT(19) 190 + #define HBG_RX_DESC_W4_MUL_CST_B BIT(18) 191 + #define HBG_RX_DESC_W4_ARP_B BIT(17) 192 + #define HBG_RX_DESC_W4_RARP_B BIT(16) 193 + #define HBG_RX_DESC_W4_ICMP_B BIT(15) 194 + #define HBG_RX_DESC_W4_VLAN_FLAG_B BIT(14) 195 + #define HBG_RX_DESC_W4_DROP_B BIT(13) 196 + #define HBG_RX_DESC_W4_L3_ERR_CODE_M GENMASK(12, 9) 197 + #define HBG_RX_DESC_W4_L2_ERR_B BIT(8) 198 + #define HBG_RX_DESC_W4_IDX_MATCH_B BIT(7) 199 + 200 + enum hbg_l3_err_code { 201 + HBG_L3_OK = 0, 202 + HBG_L3_WRONG_HEAD, 203 + HBG_L3_CSUM_ERR, 204 + HBG_L3_LEN_ERR, 205 + HBG_L3_ZERO_TTL, 206 + HBG_L3_RSVD, 207 + }; 208 + 209 + enum hbg_l4_err_code { 210 + HBG_L4_OK = 0, 211 + HBG_L4_WRONG_HEAD, 212 + HBG_L4_LEN_ERR, 213 + HBG_L4_CSUM_ERR, 214 + HBG_L4_ZERO_PORT_NUM, 215 + HBG_L4_RSVD, 216 + }; 217 + 218 + enum hbg_pkt_type_code { 219 + HBG_NO_IP_PKT = 0, 220 + HBG_IP_PKT, 221 + HBG_TCP_PKT, 222 + HBG_UDP_PKT, 223 + }; 243 224 244 225 #endif
+179 -2
drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
··· 38 38 buffer->skb_dma = dma_map_single(&priv->pdev->dev, 39 39 buffer->skb->data, buffer->skb_len, 40 40 buffer_to_dma_dir(buffer)); 41 - if (unlikely(dma_mapping_error(&priv->pdev->dev, buffer->skb_dma))) 41 + if (unlikely(dma_mapping_error(&priv->pdev->dev, buffer->skb_dma))) { 42 + if (buffer->dir == HBG_DIR_RX) 43 + priv->stats.rx_dma_err_cnt++; 44 + else 45 + priv->stats.tx_dma_err_cnt++; 46 + 42 47 return -ENOMEM; 48 + } 43 49 44 50 return 0; 45 51 } ··· 201 195 return packet_done; 202 196 } 203 197 198 + static bool hbg_rx_check_l3l4_error(struct hbg_priv *priv, 199 + struct hbg_rx_desc *desc, 200 + struct sk_buff *skb) 201 + { 202 + bool rx_checksum_offload = !!(priv->netdev->features & NETIF_F_RXCSUM); 203 + 204 + skb->ip_summed = rx_checksum_offload ? 205 + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; 206 + 207 + if (likely(!FIELD_GET(HBG_RX_DESC_W4_L3_ERR_CODE_M, desc->word4) && 208 + !FIELD_GET(HBG_RX_DESC_W4_L4_ERR_CODE_M, desc->word4))) 209 + return true; 210 + 211 + switch (FIELD_GET(HBG_RX_DESC_W4_L3_ERR_CODE_M, desc->word4)) { 212 + case HBG_L3_OK: 213 + break; 214 + case HBG_L3_WRONG_HEAD: 215 + priv->stats.rx_desc_l3_wrong_head_cnt++; 216 + return false; 217 + case HBG_L3_CSUM_ERR: 218 + skb->ip_summed = CHECKSUM_NONE; 219 + priv->stats.rx_desc_l3_csum_err_cnt++; 220 + 221 + /* Don't drop packets on csum validation failure, 222 + * suggest by Jakub 223 + */ 224 + break; 225 + case HBG_L3_LEN_ERR: 226 + priv->stats.rx_desc_l3_len_err_cnt++; 227 + return false; 228 + case HBG_L3_ZERO_TTL: 229 + priv->stats.rx_desc_l3_zero_ttl_cnt++; 230 + return false; 231 + default: 232 + priv->stats.rx_desc_l3_other_cnt++; 233 + return false; 234 + } 235 + 236 + switch (FIELD_GET(HBG_RX_DESC_W4_L4_ERR_CODE_M, desc->word4)) { 237 + case HBG_L4_OK: 238 + break; 239 + case HBG_L4_WRONG_HEAD: 240 + priv->stats.rx_desc_l4_wrong_head_cnt++; 241 + return false; 242 + case HBG_L4_LEN_ERR: 243 + priv->stats.rx_desc_l4_len_err_cnt++; 244 + return false; 245 + case HBG_L4_CSUM_ERR: 246 + skb->ip_summed = CHECKSUM_NONE; 247 + priv->stats.rx_desc_l4_csum_err_cnt++; 248 + 249 + /* Don't drop packets on csum validation failure, 250 + * suggest by Jakub 251 + */ 252 + break; 253 + case HBG_L4_ZERO_PORT_NUM: 254 + priv->stats.rx_desc_l4_zero_port_num_cnt++; 255 + return false; 256 + default: 257 + priv->stats.rx_desc_l4_other_cnt++; 258 + return false; 259 + } 260 + 261 + return true; 262 + } 263 + 264 + static void hbg_update_rx_ip_protocol_stats(struct hbg_priv *priv, 265 + struct hbg_rx_desc *desc) 266 + { 267 + if (unlikely(!FIELD_GET(HBG_RX_DESC_W4_IP_TCP_UDP_M, desc->word4))) { 268 + priv->stats.rx_desc_no_ip_pkt_cnt++; 269 + return; 270 + } 271 + 272 + if (unlikely(FIELD_GET(HBG_RX_DESC_W4_IP_VERSION_ERR_B, desc->word4))) { 273 + priv->stats.rx_desc_ip_ver_err_cnt++; 274 + return; 275 + } 276 + 277 + /* 0:ipv4, 1:ipv6 */ 278 + if (FIELD_GET(HBG_RX_DESC_W4_IP_VERSION_B, desc->word4)) 279 + priv->stats.rx_desc_ipv6_pkt_cnt++; 280 + else 281 + priv->stats.rx_desc_ipv4_pkt_cnt++; 282 + 283 + switch (FIELD_GET(HBG_RX_DESC_W4_IP_TCP_UDP_M, desc->word4)) { 284 + case HBG_IP_PKT: 285 + priv->stats.rx_desc_ip_pkt_cnt++; 286 + if (FIELD_GET(HBG_RX_DESC_W4_OPT_B, desc->word4)) 287 + priv->stats.rx_desc_ip_opt_pkt_cnt++; 288 + if (FIELD_GET(HBG_RX_DESC_W4_FRAG_B, desc->word4)) 289 + priv->stats.rx_desc_frag_cnt++; 290 + 291 + if (FIELD_GET(HBG_RX_DESC_W4_ICMP_B, desc->word4)) 292 + priv->stats.rx_desc_icmp_pkt_cnt++; 293 + else if (FIELD_GET(HBG_RX_DESC_W4_IPSEC_B, desc->word4)) 294 + priv->stats.rx_desc_ipsec_pkt_cnt++; 295 + break; 296 + case HBG_TCP_PKT: 297 + priv->stats.rx_desc_tcp_pkt_cnt++; 298 + break; 299 + case HBG_UDP_PKT: 300 + priv->stats.rx_desc_udp_pkt_cnt++; 301 + break; 302 + default: 303 + priv->stats.rx_desc_no_ip_pkt_cnt++; 304 + break; 305 + } 306 + } 307 + 308 + static void hbg_update_rx_protocol_stats(struct hbg_priv *priv, 309 + struct hbg_rx_desc *desc) 310 + { 311 + if (unlikely(!FIELD_GET(HBG_RX_DESC_W4_IDX_MATCH_B, desc->word4))) { 312 + priv->stats.rx_desc_key_not_match_cnt++; 313 + return; 314 + } 315 + 316 + if (FIELD_GET(HBG_RX_DESC_W4_BRD_CST_B, desc->word4)) 317 + priv->stats.rx_desc_broadcast_pkt_cnt++; 318 + else if (FIELD_GET(HBG_RX_DESC_W4_MUL_CST_B, desc->word4)) 319 + priv->stats.rx_desc_multicast_pkt_cnt++; 320 + 321 + if (FIELD_GET(HBG_RX_DESC_W4_VLAN_FLAG_B, desc->word4)) 322 + priv->stats.rx_desc_vlan_pkt_cnt++; 323 + 324 + if (FIELD_GET(HBG_RX_DESC_W4_ARP_B, desc->word4)) { 325 + priv->stats.rx_desc_arp_pkt_cnt++; 326 + return; 327 + } else if (FIELD_GET(HBG_RX_DESC_W4_RARP_B, desc->word4)) { 328 + priv->stats.rx_desc_rarp_pkt_cnt++; 329 + return; 330 + } 331 + 332 + hbg_update_rx_ip_protocol_stats(priv, desc); 333 + } 334 + 335 + static bool hbg_rx_pkt_check(struct hbg_priv *priv, struct hbg_rx_desc *desc, 336 + struct sk_buff *skb) 337 + { 338 + if (unlikely(FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, desc->word2) > 339 + priv->dev_specs.max_frame_len)) { 340 + priv->stats.rx_desc_pkt_len_err_cnt++; 341 + return false; 342 + } 343 + 344 + if (unlikely(FIELD_GET(HBG_RX_DESC_W2_PORT_NUM_M, desc->word2) != 345 + priv->dev_specs.mac_id || 346 + FIELD_GET(HBG_RX_DESC_W4_DROP_B, desc->word4))) { 347 + priv->stats.rx_desc_drop++; 348 + return false; 349 + } 350 + 351 + if (unlikely(FIELD_GET(HBG_RX_DESC_W4_L2_ERR_B, desc->word4))) { 352 + priv->stats.rx_desc_l2_err_cnt++; 353 + return false; 354 + } 355 + 356 + if (unlikely(!hbg_rx_check_l3l4_error(priv, desc, skb))) { 357 + priv->stats.rx_desc_l3l4_err_cnt++; 358 + return false; 359 + } 360 + 361 + hbg_update_rx_protocol_stats(priv, desc); 362 + return true; 363 + } 364 + 204 365 static int hbg_rx_fill_one_buffer(struct hbg_priv *priv) 205 366 { 206 367 struct hbg_ring *ring = &priv->rx_ring; ··· 430 257 rx_desc = (struct hbg_rx_desc *)buffer->skb->data; 431 258 pkt_len = FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2); 432 259 433 - hbg_dma_unmap(buffer); 260 + if (unlikely(!hbg_rx_pkt_check(priv, rx_desc, buffer->skb))) { 261 + hbg_buffer_free(buffer); 262 + goto next_buffer; 263 + } 434 264 265 + hbg_dma_unmap(buffer); 435 266 skb_reserve(buffer->skb, HBG_PACKET_HEAD_SIZE + NET_IP_ALIGN); 436 267 skb_put(buffer->skb, pkt_len); 437 268 buffer->skb->protocol = eth_type_trans(buffer->skb,