1511e6bc0Shuangdaode /* 2511e6bc0Shuangdaode * Copyright (c) 2014-2015 Hisilicon Limited. 3511e6bc0Shuangdaode * 4511e6bc0Shuangdaode * This program is free software; you can redistribute it and/or modify 5511e6bc0Shuangdaode * it under the terms of the GNU General Public License as published by 6511e6bc0Shuangdaode * the Free Software Foundation; either version 2 of the License, or 7511e6bc0Shuangdaode * (at your option) any later version. 8511e6bc0Shuangdaode */ 9511e6bc0Shuangdaode 10511e6bc0Shuangdaode #include <linux/delay.h> 11511e6bc0Shuangdaode #include <linux/of_mdio.h> 12511e6bc0Shuangdaode #include "hns_dsaf_main.h" 13511e6bc0Shuangdaode #include "hns_dsaf_mac.h" 14511e6bc0Shuangdaode #include "hns_dsaf_gmac.h" 15511e6bc0Shuangdaode 16511e6bc0Shuangdaode static const struct mac_stats_string g_gmac_stats_string[] = { 17511e6bc0Shuangdaode {"gmac_rx_octets_total_ok", MAC_STATS_FIELD_OFF(rx_good_bytes)}, 18511e6bc0Shuangdaode {"gmac_rx_octets_bad", MAC_STATS_FIELD_OFF(rx_bad_bytes)}, 19511e6bc0Shuangdaode {"gmac_rx_uc_pkts", MAC_STATS_FIELD_OFF(rx_uc_pkts)}, 20dafa6b0dSFabian Frederick {"gmac_rx_mc_pkts", MAC_STATS_FIELD_OFF(rx_mc_pkts)}, 21511e6bc0Shuangdaode {"gmac_rx_bc_pkts", MAC_STATS_FIELD_OFF(rx_bc_pkts)}, 22511e6bc0Shuangdaode {"gmac_rx_pkts_64octets", MAC_STATS_FIELD_OFF(rx_64bytes)}, 23511e6bc0Shuangdaode {"gmac_rx_pkts_65to127", MAC_STATS_FIELD_OFF(rx_65to127)}, 24511e6bc0Shuangdaode {"gmac_rx_pkts_128to255", MAC_STATS_FIELD_OFF(rx_128to255)}, 25511e6bc0Shuangdaode {"gmac_rx_pkts_256to511", MAC_STATS_FIELD_OFF(rx_256to511)}, 26511e6bc0Shuangdaode {"gmac_rx_pkts_512to1023", MAC_STATS_FIELD_OFF(rx_512to1023)}, 27511e6bc0Shuangdaode {"gmac_rx_pkts_1024to1518", MAC_STATS_FIELD_OFF(rx_1024to1518)}, 28511e6bc0Shuangdaode {"gmac_rx_pkts_1519tomax", MAC_STATS_FIELD_OFF(rx_1519tomax)}, 29511e6bc0Shuangdaode {"gmac_rx_fcs_errors", MAC_STATS_FIELD_OFF(rx_fcs_err)}, 30511e6bc0Shuangdaode {"gmac_rx_tagged", MAC_STATS_FIELD_OFF(rx_vlan_pkts)}, 31511e6bc0Shuangdaode {"gmac_rx_data_err", MAC_STATS_FIELD_OFF(rx_data_err)}, 32511e6bc0Shuangdaode {"gmac_rx_align_errors", MAC_STATS_FIELD_OFF(rx_align_err)}, 33511e6bc0Shuangdaode {"gmac_rx_long_errors", MAC_STATS_FIELD_OFF(rx_oversize)}, 34511e6bc0Shuangdaode {"gmac_rx_jabber_errors", MAC_STATS_FIELD_OFF(rx_jabber_err)}, 35511e6bc0Shuangdaode {"gmac_rx_pause_maccontrol", MAC_STATS_FIELD_OFF(rx_pfc_tc0)}, 36511e6bc0Shuangdaode {"gmac_rx_unknown_maccontrol", MAC_STATS_FIELD_OFF(rx_unknown_ctrl)}, 37511e6bc0Shuangdaode {"gmac_rx_very_long_err", MAC_STATS_FIELD_OFF(rx_long_err)}, 38511e6bc0Shuangdaode {"gmac_rx_runt_err", MAC_STATS_FIELD_OFF(rx_minto64)}, 39511e6bc0Shuangdaode {"gmac_rx_short_err", MAC_STATS_FIELD_OFF(rx_under_min)}, 4028b30124SQianqian Xie {"gmac_rx_filt_pkt", MAC_STATS_FIELD_OFF(rx_filter_pkts)}, 4128b30124SQianqian Xie {"gmac_rx_octets_total_filt", MAC_STATS_FIELD_OFF(rx_filter_bytes)}, 42511e6bc0Shuangdaode {"gmac_rx_overrun_cnt", MAC_STATS_FIELD_OFF(rx_fifo_overrun_err)}, 43511e6bc0Shuangdaode {"gmac_rx_length_err", MAC_STATS_FIELD_OFF(rx_len_err)}, 44511e6bc0Shuangdaode {"gmac_rx_fail_comma", MAC_STATS_FIELD_OFF(rx_comma_err)}, 45511e6bc0Shuangdaode 46511e6bc0Shuangdaode {"gmac_tx_octets_ok", MAC_STATS_FIELD_OFF(tx_good_bytes)}, 47511e6bc0Shuangdaode {"gmac_tx_octets_bad", MAC_STATS_FIELD_OFF(tx_bad_bytes)}, 48511e6bc0Shuangdaode {"gmac_tx_uc_pkts", MAC_STATS_FIELD_OFF(tx_uc_pkts)}, 49511e6bc0Shuangdaode {"gmac_tx_mc_pkts", MAC_STATS_FIELD_OFF(tx_mc_pkts)}, 50511e6bc0Shuangdaode {"gmac_tx_bc_pkts", MAC_STATS_FIELD_OFF(tx_bc_pkts)}, 51511e6bc0Shuangdaode {"gmac_tx_pkts_64octets", MAC_STATS_FIELD_OFF(tx_64bytes)}, 52511e6bc0Shuangdaode {"gmac_tx_pkts_65to127", MAC_STATS_FIELD_OFF(tx_65to127)}, 53511e6bc0Shuangdaode {"gmac_tx_pkts_128to255", MAC_STATS_FIELD_OFF(tx_128to255)}, 54511e6bc0Shuangdaode {"gmac_tx_pkts_256to511", MAC_STATS_FIELD_OFF(tx_256to511)}, 55511e6bc0Shuangdaode {"gmac_tx_pkts_512to1023", MAC_STATS_FIELD_OFF(tx_512to1023)}, 56511e6bc0Shuangdaode {"gmac_tx_pkts_1024to1518", MAC_STATS_FIELD_OFF(tx_1024to1518)}, 57511e6bc0Shuangdaode {"gmac_tx_pkts_1519tomax", MAC_STATS_FIELD_OFF(tx_1519tomax)}, 58511e6bc0Shuangdaode {"gmac_tx_excessive_length_drop", MAC_STATS_FIELD_OFF(tx_jabber_err)}, 59511e6bc0Shuangdaode {"gmac_tx_underrun", MAC_STATS_FIELD_OFF(tx_underrun_err)}, 60511e6bc0Shuangdaode {"gmac_tx_tagged", MAC_STATS_FIELD_OFF(tx_vlan)}, 61511e6bc0Shuangdaode {"gmac_tx_crc_error", MAC_STATS_FIELD_OFF(tx_crc_err)}, 62511e6bc0Shuangdaode {"gmac_tx_pause_frames", MAC_STATS_FIELD_OFF(tx_pfc_tc0)} 63511e6bc0Shuangdaode }; 64511e6bc0Shuangdaode 65511e6bc0Shuangdaode static void hns_gmac_enable(void *mac_drv, enum mac_commom_mode mode) 66511e6bc0Shuangdaode { 67511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 68511e6bc0Shuangdaode 69511e6bc0Shuangdaode /*enable GE rX/tX */ 70511e6bc0Shuangdaode if ((mode == MAC_COMM_MODE_TX) || (mode == MAC_COMM_MODE_RX_AND_TX)) 71511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_TX_EN_B, 1); 72511e6bc0Shuangdaode 73511e6bc0Shuangdaode if ((mode == MAC_COMM_MODE_RX) || (mode == MAC_COMM_MODE_RX_AND_TX)) 74511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_RX_EN_B, 1); 75511e6bc0Shuangdaode } 76511e6bc0Shuangdaode 77511e6bc0Shuangdaode static void hns_gmac_disable(void *mac_drv, enum mac_commom_mode mode) 78511e6bc0Shuangdaode { 79511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 80511e6bc0Shuangdaode 81511e6bc0Shuangdaode /*disable GE rX/tX */ 82511e6bc0Shuangdaode if ((mode == MAC_COMM_MODE_TX) || (mode == MAC_COMM_MODE_RX_AND_TX)) 83511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_TX_EN_B, 0); 84511e6bc0Shuangdaode 85511e6bc0Shuangdaode if ((mode == MAC_COMM_MODE_RX) || (mode == MAC_COMM_MODE_RX_AND_TX)) 86511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_RX_EN_B, 0); 87511e6bc0Shuangdaode } 88511e6bc0Shuangdaode 89b4957ab0SSalil /* hns_gmac_get_en - get port enable 90511e6bc0Shuangdaode * @mac_drv:mac device 91511e6bc0Shuangdaode * @rx:rx enable 92511e6bc0Shuangdaode * @tx:tx enable 93511e6bc0Shuangdaode */ 94511e6bc0Shuangdaode static void hns_gmac_get_en(void *mac_drv, u32 *rx, u32 *tx) 95511e6bc0Shuangdaode { 96511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 97511e6bc0Shuangdaode u32 porten; 98511e6bc0Shuangdaode 99511e6bc0Shuangdaode porten = dsaf_read_dev(drv, GMAC_PORT_EN_REG); 100511e6bc0Shuangdaode *tx = dsaf_get_bit(porten, GMAC_PORT_TX_EN_B); 101511e6bc0Shuangdaode *rx = dsaf_get_bit(porten, GMAC_PORT_RX_EN_B); 102511e6bc0Shuangdaode } 103511e6bc0Shuangdaode 104511e6bc0Shuangdaode static void hns_gmac_free(void *mac_drv) 105511e6bc0Shuangdaode { 106511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 107511e6bc0Shuangdaode struct dsaf_device *dsaf_dev 108511e6bc0Shuangdaode = (struct dsaf_device *)dev_get_drvdata(drv->dev); 109511e6bc0Shuangdaode 110511e6bc0Shuangdaode u32 mac_id = drv->mac_id; 111511e6bc0Shuangdaode 112a24274aaSKejian Yan dsaf_dev->misc_op->ge_srst(dsaf_dev, mac_id, 0); 113511e6bc0Shuangdaode } 114511e6bc0Shuangdaode 115511e6bc0Shuangdaode static void hns_gmac_set_tx_auto_pause_frames(void *mac_drv, u16 newval) 116511e6bc0Shuangdaode { 117511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 118511e6bc0Shuangdaode 119511e6bc0Shuangdaode dsaf_set_dev_field(drv, GMAC_FC_TX_TIMER_REG, GMAC_FC_TX_TIMER_M, 120511e6bc0Shuangdaode GMAC_FC_TX_TIMER_S, newval); 121511e6bc0Shuangdaode } 122511e6bc0Shuangdaode 123511e6bc0Shuangdaode static void hns_gmac_get_tx_auto_pause_frames(void *mac_drv, u16 *newval) 124511e6bc0Shuangdaode { 125511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 126511e6bc0Shuangdaode 127511e6bc0Shuangdaode *newval = dsaf_get_dev_field(drv, GMAC_FC_TX_TIMER_REG, 128511e6bc0Shuangdaode GMAC_FC_TX_TIMER_M, GMAC_FC_TX_TIMER_S); 129511e6bc0Shuangdaode } 130511e6bc0Shuangdaode 131511e6bc0Shuangdaode static void hns_gmac_set_rx_auto_pause_frames(void *mac_drv, u32 newval) 132511e6bc0Shuangdaode { 133511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 134511e6bc0Shuangdaode 135511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_PAUSE_EN_REG, 136511e6bc0Shuangdaode GMAC_PAUSE_EN_RX_FDFC_B, !!newval); 137511e6bc0Shuangdaode } 138511e6bc0Shuangdaode 139511e6bc0Shuangdaode static void hns_gmac_config_max_frame_length(void *mac_drv, u16 newval) 140511e6bc0Shuangdaode { 141511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 142511e6bc0Shuangdaode 143511e6bc0Shuangdaode dsaf_set_dev_field(drv, GMAC_MAX_FRM_SIZE_REG, GMAC_MAX_FRM_SIZE_M, 144511e6bc0Shuangdaode GMAC_MAX_FRM_SIZE_S, newval); 145511e6bc0Shuangdaode 146511e6bc0Shuangdaode dsaf_set_dev_field(drv, GAMC_RX_MAX_FRAME, GMAC_MAX_FRM_SIZE_M, 147511e6bc0Shuangdaode GMAC_MAX_FRM_SIZE_S, newval); 148511e6bc0Shuangdaode } 149511e6bc0Shuangdaode 150de99208cSlipeng static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval) 151de99208cSlipeng { 152de99208cSlipeng u32 tx_ctrl; 153de99208cSlipeng struct mac_driver *drv = (struct mac_driver *)mac_drv; 154de99208cSlipeng 155de99208cSlipeng tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG); 156de99208cSlipeng dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval); 157de99208cSlipeng dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval); 158de99208cSlipeng dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl); 159de99208cSlipeng } 160de99208cSlipeng 161511e6bc0Shuangdaode static void hns_gmac_config_an_mode(void *mac_drv, u8 newval) 162511e6bc0Shuangdaode { 163511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 164511e6bc0Shuangdaode 165511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_TRANSMIT_CONTROL_REG, 166511e6bc0Shuangdaode GMAC_TX_AN_EN_B, !!newval); 167511e6bc0Shuangdaode } 168511e6bc0Shuangdaode 169511e6bc0Shuangdaode static void hns_gmac_tx_loop_pkt_dis(void *mac_drv) 170511e6bc0Shuangdaode { 171511e6bc0Shuangdaode u32 tx_loop_pkt_pri; 172511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 173511e6bc0Shuangdaode 174511e6bc0Shuangdaode tx_loop_pkt_pri = dsaf_read_dev(drv, GMAC_TX_LOOP_PKT_PRI_REG); 175511e6bc0Shuangdaode dsaf_set_bit(tx_loop_pkt_pri, GMAC_TX_LOOP_PKT_EN_B, 1); 176511e6bc0Shuangdaode dsaf_set_bit(tx_loop_pkt_pri, GMAC_TX_LOOP_PKT_HIG_PRI_B, 0); 177511e6bc0Shuangdaode dsaf_write_dev(drv, GMAC_TX_LOOP_PKT_PRI_REG, tx_loop_pkt_pri); 178511e6bc0Shuangdaode } 179511e6bc0Shuangdaode 180511e6bc0Shuangdaode static void hns_gmac_set_duplex_type(void *mac_drv, u8 newval) 181511e6bc0Shuangdaode { 182511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 183511e6bc0Shuangdaode 184511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_DUPLEX_TYPE_REG, 185511e6bc0Shuangdaode GMAC_DUPLEX_TYPE_B, !!newval); 186511e6bc0Shuangdaode } 187511e6bc0Shuangdaode 188511e6bc0Shuangdaode static void hns_gmac_get_duplex_type(void *mac_drv, 189511e6bc0Shuangdaode enum hns_gmac_duplex_mdoe *duplex_mode) 190511e6bc0Shuangdaode { 191511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 192511e6bc0Shuangdaode 193511e6bc0Shuangdaode *duplex_mode = (enum hns_gmac_duplex_mdoe)dsaf_get_dev_bit( 194511e6bc0Shuangdaode drv, GMAC_DUPLEX_TYPE_REG, GMAC_DUPLEX_TYPE_B); 195511e6bc0Shuangdaode } 196511e6bc0Shuangdaode 197511e6bc0Shuangdaode static void hns_gmac_get_port_mode(void *mac_drv, enum hns_port_mode *port_mode) 198511e6bc0Shuangdaode { 199511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 200511e6bc0Shuangdaode 201511e6bc0Shuangdaode *port_mode = (enum hns_port_mode)dsaf_get_dev_field( 202511e6bc0Shuangdaode drv, GMAC_PORT_MODE_REG, GMAC_PORT_MODE_M, GMAC_PORT_MODE_S); 203511e6bc0Shuangdaode } 204511e6bc0Shuangdaode 205511e6bc0Shuangdaode static void hns_gmac_port_mode_get(void *mac_drv, 206511e6bc0Shuangdaode struct hns_gmac_port_mode_cfg *port_mode) 207511e6bc0Shuangdaode { 208511e6bc0Shuangdaode u32 tx_ctrl; 209511e6bc0Shuangdaode u32 recv_ctrl; 210511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 211511e6bc0Shuangdaode 212511e6bc0Shuangdaode port_mode->port_mode = (enum hns_port_mode)dsaf_get_dev_field( 213511e6bc0Shuangdaode drv, GMAC_PORT_MODE_REG, GMAC_PORT_MODE_M, GMAC_PORT_MODE_S); 214511e6bc0Shuangdaode 215511e6bc0Shuangdaode tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG); 216511e6bc0Shuangdaode recv_ctrl = dsaf_read_dev(drv, GMAC_RECV_CONTROL_REG); 217511e6bc0Shuangdaode 218511e6bc0Shuangdaode port_mode->max_frm_size = 219511e6bc0Shuangdaode dsaf_get_dev_field(drv, GMAC_MAX_FRM_SIZE_REG, 220511e6bc0Shuangdaode GMAC_MAX_FRM_SIZE_M, GMAC_MAX_FRM_SIZE_S); 221511e6bc0Shuangdaode port_mode->short_runts_thr = 222511e6bc0Shuangdaode dsaf_get_dev_field(drv, GMAC_SHORT_RUNTS_THR_REG, 223511e6bc0Shuangdaode GMAC_SHORT_RUNTS_THR_M, 224511e6bc0Shuangdaode GMAC_SHORT_RUNTS_THR_S); 225511e6bc0Shuangdaode 226511e6bc0Shuangdaode port_mode->pad_enable = dsaf_get_bit(tx_ctrl, GMAC_TX_PAD_EN_B); 227511e6bc0Shuangdaode port_mode->crc_add = dsaf_get_bit(tx_ctrl, GMAC_TX_CRC_ADD_B); 228511e6bc0Shuangdaode port_mode->an_enable = dsaf_get_bit(tx_ctrl, GMAC_TX_AN_EN_B); 229511e6bc0Shuangdaode 230511e6bc0Shuangdaode port_mode->runt_pkt_en = 231511e6bc0Shuangdaode dsaf_get_bit(recv_ctrl, GMAC_RECV_CTRL_RUNT_PKT_EN_B); 232511e6bc0Shuangdaode port_mode->strip_pad_en = 233511e6bc0Shuangdaode dsaf_get_bit(recv_ctrl, GMAC_RECV_CTRL_STRIP_PAD_EN_B); 234511e6bc0Shuangdaode } 235511e6bc0Shuangdaode 236511e6bc0Shuangdaode static void hns_gmac_pause_frm_cfg(void *mac_drv, u32 rx_pause_en, 237511e6bc0Shuangdaode u32 tx_pause_en) 238511e6bc0Shuangdaode { 239511e6bc0Shuangdaode u32 pause_en; 240511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 241511e6bc0Shuangdaode 242511e6bc0Shuangdaode pause_en = dsaf_read_dev(drv, GMAC_PAUSE_EN_REG); 243511e6bc0Shuangdaode dsaf_set_bit(pause_en, GMAC_PAUSE_EN_RX_FDFC_B, !!rx_pause_en); 244511e6bc0Shuangdaode dsaf_set_bit(pause_en, GMAC_PAUSE_EN_TX_FDFC_B, !!tx_pause_en); 245511e6bc0Shuangdaode dsaf_write_dev(drv, GMAC_PAUSE_EN_REG, pause_en); 246511e6bc0Shuangdaode } 247511e6bc0Shuangdaode 248511e6bc0Shuangdaode static void hns_gmac_get_pausefrm_cfg(void *mac_drv, u32 *rx_pause_en, 249511e6bc0Shuangdaode u32 *tx_pause_en) 250511e6bc0Shuangdaode { 251511e6bc0Shuangdaode u32 pause_en; 252511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 253511e6bc0Shuangdaode 254511e6bc0Shuangdaode pause_en = dsaf_read_dev(drv, GMAC_PAUSE_EN_REG); 255511e6bc0Shuangdaode 256511e6bc0Shuangdaode *rx_pause_en = dsaf_get_bit(pause_en, GMAC_PAUSE_EN_RX_FDFC_B); 257511e6bc0Shuangdaode *tx_pause_en = dsaf_get_bit(pause_en, GMAC_PAUSE_EN_TX_FDFC_B); 258511e6bc0Shuangdaode } 259511e6bc0Shuangdaode 260511e6bc0Shuangdaode static int hns_gmac_adjust_link(void *mac_drv, enum mac_speed speed, 261511e6bc0Shuangdaode u32 full_duplex) 262511e6bc0Shuangdaode { 263511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 264511e6bc0Shuangdaode 265511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_DUPLEX_TYPE_REG, 266511e6bc0Shuangdaode GMAC_DUPLEX_TYPE_B, !!full_duplex); 267511e6bc0Shuangdaode 268511e6bc0Shuangdaode switch (speed) { 269511e6bc0Shuangdaode case MAC_SPEED_10: 270511e6bc0Shuangdaode dsaf_set_dev_field( 271511e6bc0Shuangdaode drv, GMAC_PORT_MODE_REG, 272511e6bc0Shuangdaode GMAC_PORT_MODE_M, GMAC_PORT_MODE_S, 0x6); 273511e6bc0Shuangdaode break; 274511e6bc0Shuangdaode case MAC_SPEED_100: 275511e6bc0Shuangdaode dsaf_set_dev_field( 276511e6bc0Shuangdaode drv, GMAC_PORT_MODE_REG, 277511e6bc0Shuangdaode GMAC_PORT_MODE_M, GMAC_PORT_MODE_S, 0x7); 278511e6bc0Shuangdaode break; 279511e6bc0Shuangdaode case MAC_SPEED_1000: 280511e6bc0Shuangdaode dsaf_set_dev_field( 281511e6bc0Shuangdaode drv, GMAC_PORT_MODE_REG, 282511e6bc0Shuangdaode GMAC_PORT_MODE_M, GMAC_PORT_MODE_S, 0x8); 283511e6bc0Shuangdaode break; 284511e6bc0Shuangdaode default: 285511e6bc0Shuangdaode dev_err(drv->dev, 286511e6bc0Shuangdaode "hns_gmac_adjust_link fail, speed%d mac%d\n", 287511e6bc0Shuangdaode speed, drv->mac_id); 288511e6bc0Shuangdaode return -EINVAL; 289511e6bc0Shuangdaode } 290511e6bc0Shuangdaode 291511e6bc0Shuangdaode return 0; 292511e6bc0Shuangdaode } 293511e6bc0Shuangdaode 294d5679849SKejian Yan static void hns_gmac_set_uc_match(void *mac_drv, u16 en) 295d5679849SKejian Yan { 296d5679849SKejian Yan struct mac_driver *drv = mac_drv; 297d5679849SKejian Yan 298d5679849SKejian Yan dsaf_set_dev_bit(drv, GMAC_REC_FILT_CONTROL_REG, 299d5679849SKejian Yan GMAC_UC_MATCH_EN_B, !en); 300d5679849SKejian Yan dsaf_set_dev_bit(drv, GMAC_STATION_ADDR_HIGH_2_REG, 301d5679849SKejian Yan GMAC_ADDR_EN_B, !en); 302d5679849SKejian Yan } 303d5679849SKejian Yan 304d5679849SKejian Yan static void hns_gmac_set_promisc(void *mac_drv, u8 en) 305d5679849SKejian Yan { 306d5679849SKejian Yan struct mac_driver *drv = mac_drv; 307d5679849SKejian Yan 308d5679849SKejian Yan if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG) 309d5679849SKejian Yan hns_gmac_set_uc_match(mac_drv, en); 310d5679849SKejian Yan } 311d5679849SKejian Yan 312511e6bc0Shuangdaode static void hns_gmac_init(void *mac_drv) 313511e6bc0Shuangdaode { 314511e6bc0Shuangdaode u32 port; 315511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 316511e6bc0Shuangdaode struct dsaf_device *dsaf_dev 317511e6bc0Shuangdaode = (struct dsaf_device *)dev_get_drvdata(drv->dev); 318511e6bc0Shuangdaode 319511e6bc0Shuangdaode port = drv->mac_id; 320511e6bc0Shuangdaode 321a24274aaSKejian Yan dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 0); 322511e6bc0Shuangdaode mdelay(10); 323a24274aaSKejian Yan dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 1); 324511e6bc0Shuangdaode mdelay(10); 325511e6bc0Shuangdaode hns_gmac_disable(mac_drv, MAC_COMM_MODE_RX_AND_TX); 326511e6bc0Shuangdaode hns_gmac_tx_loop_pkt_dis(mac_drv); 327d5679849SKejian Yan if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG) 328d5679849SKejian Yan hns_gmac_set_uc_match(mac_drv, 0); 32987ff7e1fSlipeng 330de99208cSlipeng hns_gmac_config_pad_and_crc(mac_drv, 1); 331de99208cSlipeng 332de99208cSlipeng dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG, 333de99208cSlipeng GMAC_MODE_CHANGE_EB_B, 1); 334de99208cSlipeng 33587ff7e1fSlipeng /* reduce gmac tx water line to avoid gmac hang-up 33687ff7e1fSlipeng * in speed 100M and duplex half. 33787ff7e1fSlipeng */ 33887ff7e1fSlipeng dsaf_set_dev_field(drv, GMAC_TX_WATER_LINE_REG, GMAC_TX_WATER_LINE_MASK, 33987ff7e1fSlipeng GMAC_TX_WATER_LINE_SHIFT, 8); 340511e6bc0Shuangdaode } 341511e6bc0Shuangdaode 342336a443bSYueHaibing static void hns_gmac_update_stats(void *mac_drv) 343511e6bc0Shuangdaode { 344511e6bc0Shuangdaode struct mac_hw_stats *hw_stats = NULL; 345511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 346511e6bc0Shuangdaode 347511e6bc0Shuangdaode hw_stats = &drv->mac_cb->hw_stats; 348511e6bc0Shuangdaode 349511e6bc0Shuangdaode /* RX */ 350511e6bc0Shuangdaode hw_stats->rx_good_bytes 351511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_OK_REG); 352511e6bc0Shuangdaode hw_stats->rx_bad_bytes 353511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_OCTETS_BAD_REG); 354511e6bc0Shuangdaode hw_stats->rx_uc_pkts += dsaf_read_dev(drv, GMAC_RX_UC_PKTS_REG); 355511e6bc0Shuangdaode hw_stats->rx_mc_pkts += dsaf_read_dev(drv, GMAC_RX_MC_PKTS_REG); 356511e6bc0Shuangdaode hw_stats->rx_bc_pkts += dsaf_read_dev(drv, GMAC_RX_BC_PKTS_REG); 357511e6bc0Shuangdaode hw_stats->rx_64bytes 358511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_64OCTETS_REG); 359511e6bc0Shuangdaode hw_stats->rx_65to127 360511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_65TO127OCTETS_REG); 361511e6bc0Shuangdaode hw_stats->rx_128to255 362511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_128TO255OCTETS_REG); 363511e6bc0Shuangdaode hw_stats->rx_256to511 364511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_255TO511OCTETS_REG); 365511e6bc0Shuangdaode hw_stats->rx_512to1023 366511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_512TO1023OCTETS_REG); 367511e6bc0Shuangdaode hw_stats->rx_1024to1518 368511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_1024TO1518OCTETS_REG); 369511e6bc0Shuangdaode hw_stats->rx_1519tomax 370511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_1519TOMAXOCTETS_REG); 371511e6bc0Shuangdaode hw_stats->rx_fcs_err += dsaf_read_dev(drv, GMAC_RX_FCS_ERRORS_REG); 372511e6bc0Shuangdaode hw_stats->rx_vlan_pkts += dsaf_read_dev(drv, GMAC_RX_TAGGED_REG); 373511e6bc0Shuangdaode hw_stats->rx_data_err += dsaf_read_dev(drv, GMAC_RX_DATA_ERR_REG); 374511e6bc0Shuangdaode hw_stats->rx_align_err 375511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_ALIGN_ERRORS_REG); 376511e6bc0Shuangdaode hw_stats->rx_oversize 377511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_LONG_ERRORS_REG); 378511e6bc0Shuangdaode hw_stats->rx_jabber_err 379511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_JABBER_ERRORS_REG); 380511e6bc0Shuangdaode hw_stats->rx_pfc_tc0 381511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PAUSE_MACCTRL_FRAM_REG); 382511e6bc0Shuangdaode hw_stats->rx_unknown_ctrl 383511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_UNKNOWN_MACCTRL_FRAM_REG); 384511e6bc0Shuangdaode hw_stats->rx_long_err 385511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_VERY_LONG_ERR_CNT_REG); 386511e6bc0Shuangdaode hw_stats->rx_minto64 387511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_RUNT_ERR_CNT_REG); 388511e6bc0Shuangdaode hw_stats->rx_under_min 389511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_SHORT_ERR_CNT_REG); 390511e6bc0Shuangdaode hw_stats->rx_filter_pkts 391511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_FILT_PKT_CNT_REG); 392511e6bc0Shuangdaode hw_stats->rx_filter_bytes 393511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_FILT_REG); 394511e6bc0Shuangdaode hw_stats->rx_fifo_overrun_err 395511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_OVERRUN_CNT_REG); 396511e6bc0Shuangdaode hw_stats->rx_len_err 397511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_LENGTHFIELD_ERR_CNT_REG); 398511e6bc0Shuangdaode hw_stats->rx_comma_err 399511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_FAIL_COMMA_CNT_REG); 400511e6bc0Shuangdaode 401511e6bc0Shuangdaode /* TX */ 402511e6bc0Shuangdaode hw_stats->tx_good_bytes 403511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_OK_REG); 404511e6bc0Shuangdaode hw_stats->tx_bad_bytes 405511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_BAD_REG); 406511e6bc0Shuangdaode hw_stats->tx_uc_pkts += dsaf_read_dev(drv, GMAC_TX_UC_PKTS_REG); 407511e6bc0Shuangdaode hw_stats->tx_mc_pkts += dsaf_read_dev(drv, GMAC_TX_MC_PKTS_REG); 408511e6bc0Shuangdaode hw_stats->tx_bc_pkts += dsaf_read_dev(drv, GMAC_TX_BC_PKTS_REG); 409511e6bc0Shuangdaode hw_stats->tx_64bytes 410511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_64OCTETS_REG); 411511e6bc0Shuangdaode hw_stats->tx_65to127 412511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_65TO127OCTETS_REG); 413511e6bc0Shuangdaode hw_stats->tx_128to255 414511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_128TO255OCTETS_REG); 415511e6bc0Shuangdaode hw_stats->tx_256to511 416511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_255TO511OCTETS_REG); 417511e6bc0Shuangdaode hw_stats->tx_512to1023 418511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_512TO1023OCTETS_REG); 419511e6bc0Shuangdaode hw_stats->tx_1024to1518 420511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_1024TO1518OCTETS_REG); 421511e6bc0Shuangdaode hw_stats->tx_1519tomax 422511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_1519TOMAXOCTETS_REG); 423511e6bc0Shuangdaode hw_stats->tx_jabber_err 424511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_EXCESSIVE_LENGTH_DROP_REG); 425511e6bc0Shuangdaode hw_stats->tx_underrun_err 426511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_UNDERRUN_REG); 427511e6bc0Shuangdaode hw_stats->tx_vlan += dsaf_read_dev(drv, GMAC_TX_TAGGED_REG); 428511e6bc0Shuangdaode hw_stats->tx_crc_err += dsaf_read_dev(drv, GMAC_TX_CRC_ERROR_REG); 429511e6bc0Shuangdaode hw_stats->tx_pfc_tc0 430511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PAUSE_FRAMES_REG); 431511e6bc0Shuangdaode } 432511e6bc0Shuangdaode 433511e6bc0Shuangdaode static void hns_gmac_set_mac_addr(void *mac_drv, char *mac_addr) 434511e6bc0Shuangdaode { 435511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 436511e6bc0Shuangdaode 437511e6bc0Shuangdaode u32 high_val = mac_addr[1] | (mac_addr[0] << 8); 438511e6bc0Shuangdaode 439511e6bc0Shuangdaode u32 low_val = mac_addr[5] | (mac_addr[4] << 8) 440511e6bc0Shuangdaode | (mac_addr[3] << 16) | (mac_addr[2] << 24); 441d5679849SKejian Yan 442d5679849SKejian Yan u32 val = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG); 443d5679849SKejian Yan u32 sta_addr_en = dsaf_get_bit(val, GMAC_ADDR_EN_B); 444d5679849SKejian Yan 445511e6bc0Shuangdaode dsaf_write_dev(drv, GMAC_STATION_ADDR_LOW_2_REG, low_val); 446d5679849SKejian Yan dsaf_write_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG, 447d5679849SKejian Yan high_val | (sta_addr_en << GMAC_ADDR_EN_B)); 448511e6bc0Shuangdaode } 449511e6bc0Shuangdaode 450511e6bc0Shuangdaode static int hns_gmac_config_loopback(void *mac_drv, enum hnae_loop loop_mode, 451511e6bc0Shuangdaode u8 enable) 452511e6bc0Shuangdaode { 453511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 454511e6bc0Shuangdaode 455511e6bc0Shuangdaode switch (loop_mode) { 456511e6bc0Shuangdaode case MAC_INTERNALLOOP_MAC: 457511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_LOOP_REG, GMAC_LP_REG_CF2MI_LP_EN_B, 458511e6bc0Shuangdaode !!enable); 459511e6bc0Shuangdaode break; 460511e6bc0Shuangdaode default: 461511e6bc0Shuangdaode dev_err(drv->dev, "loop_mode error\n"); 462511e6bc0Shuangdaode return -EINVAL; 463511e6bc0Shuangdaode } 464511e6bc0Shuangdaode 465511e6bc0Shuangdaode return 0; 466511e6bc0Shuangdaode } 467511e6bc0Shuangdaode 468511e6bc0Shuangdaode static void hns_gmac_get_info(void *mac_drv, struct mac_info *mac_info) 469511e6bc0Shuangdaode { 470511e6bc0Shuangdaode enum hns_gmac_duplex_mdoe duplex; 471511e6bc0Shuangdaode enum hns_port_mode speed; 472511e6bc0Shuangdaode u32 rx_pause; 473511e6bc0Shuangdaode u32 tx_pause; 474511e6bc0Shuangdaode u32 rx; 475511e6bc0Shuangdaode u32 tx; 476511e6bc0Shuangdaode u16 fc_tx_timer; 477511e6bc0Shuangdaode struct hns_gmac_port_mode_cfg port_mode = { GMAC_10M_MII, 0 }; 478511e6bc0Shuangdaode 479511e6bc0Shuangdaode hns_gmac_port_mode_get(mac_drv, &port_mode); 480511e6bc0Shuangdaode mac_info->pad_and_crc_en = port_mode.crc_add && port_mode.pad_enable; 481511e6bc0Shuangdaode mac_info->auto_neg = port_mode.an_enable; 482511e6bc0Shuangdaode 483511e6bc0Shuangdaode hns_gmac_get_tx_auto_pause_frames(mac_drv, &fc_tx_timer); 484511e6bc0Shuangdaode mac_info->tx_pause_time = fc_tx_timer; 485511e6bc0Shuangdaode 486511e6bc0Shuangdaode hns_gmac_get_en(mac_drv, &rx, &tx); 487511e6bc0Shuangdaode mac_info->port_en = rx && tx; 488511e6bc0Shuangdaode 489511e6bc0Shuangdaode hns_gmac_get_duplex_type(mac_drv, &duplex); 490511e6bc0Shuangdaode mac_info->duplex = duplex; 491511e6bc0Shuangdaode 492511e6bc0Shuangdaode hns_gmac_get_port_mode(mac_drv, &speed); 493511e6bc0Shuangdaode switch (speed) { 494511e6bc0Shuangdaode case GMAC_10M_SGMII: 495511e6bc0Shuangdaode mac_info->speed = MAC_SPEED_10; 496511e6bc0Shuangdaode break; 497511e6bc0Shuangdaode case GMAC_100M_SGMII: 498511e6bc0Shuangdaode mac_info->speed = MAC_SPEED_100; 499511e6bc0Shuangdaode break; 500511e6bc0Shuangdaode case GMAC_1000M_SGMII: 501511e6bc0Shuangdaode mac_info->speed = MAC_SPEED_1000; 502511e6bc0Shuangdaode break; 503511e6bc0Shuangdaode default: 504511e6bc0Shuangdaode mac_info->speed = 0; 505511e6bc0Shuangdaode break; 506511e6bc0Shuangdaode } 507511e6bc0Shuangdaode 508511e6bc0Shuangdaode hns_gmac_get_pausefrm_cfg(mac_drv, &rx_pause, &tx_pause); 509511e6bc0Shuangdaode mac_info->rx_pause_en = rx_pause; 510511e6bc0Shuangdaode mac_info->tx_pause_en = tx_pause; 511511e6bc0Shuangdaode } 512511e6bc0Shuangdaode 513511e6bc0Shuangdaode static void hns_gmac_autoneg_stat(void *mac_drv, u32 *enable) 514511e6bc0Shuangdaode { 515511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 516511e6bc0Shuangdaode 517511e6bc0Shuangdaode *enable = dsaf_get_dev_bit(drv, GMAC_TRANSMIT_CONTROL_REG, 518511e6bc0Shuangdaode GMAC_TX_AN_EN_B); 519511e6bc0Shuangdaode } 520511e6bc0Shuangdaode 521511e6bc0Shuangdaode static void hns_gmac_get_link_status(void *mac_drv, u32 *link_stat) 522511e6bc0Shuangdaode { 523511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 524511e6bc0Shuangdaode 525511e6bc0Shuangdaode *link_stat = dsaf_get_dev_bit(drv, GMAC_AN_NEG_STATE_REG, 526511e6bc0Shuangdaode GMAC_AN_NEG_STAT_RX_SYNC_OK_B); 527511e6bc0Shuangdaode } 528511e6bc0Shuangdaode 529511e6bc0Shuangdaode static void hns_gmac_get_regs(void *mac_drv, void *data) 530511e6bc0Shuangdaode { 531511e6bc0Shuangdaode u32 *regs = data; 532511e6bc0Shuangdaode int i; 533511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 534511e6bc0Shuangdaode 535511e6bc0Shuangdaode /* base config registers */ 536511e6bc0Shuangdaode regs[0] = dsaf_read_dev(drv, GMAC_DUPLEX_TYPE_REG); 537511e6bc0Shuangdaode regs[1] = dsaf_read_dev(drv, GMAC_FD_FC_TYPE_REG); 538511e6bc0Shuangdaode regs[2] = dsaf_read_dev(drv, GMAC_FC_TX_TIMER_REG); 539511e6bc0Shuangdaode regs[3] = dsaf_read_dev(drv, GMAC_FD_FC_ADDR_LOW_REG); 540511e6bc0Shuangdaode regs[4] = dsaf_read_dev(drv, GMAC_FD_FC_ADDR_HIGH_REG); 541511e6bc0Shuangdaode regs[5] = dsaf_read_dev(drv, GMAC_IPG_TX_TIMER_REG); 542511e6bc0Shuangdaode regs[6] = dsaf_read_dev(drv, GMAC_PAUSE_THR_REG); 543511e6bc0Shuangdaode regs[7] = dsaf_read_dev(drv, GMAC_MAX_FRM_SIZE_REG); 544511e6bc0Shuangdaode regs[8] = dsaf_read_dev(drv, GMAC_PORT_MODE_REG); 545511e6bc0Shuangdaode regs[9] = dsaf_read_dev(drv, GMAC_PORT_EN_REG); 546511e6bc0Shuangdaode regs[10] = dsaf_read_dev(drv, GMAC_PAUSE_EN_REG); 547511e6bc0Shuangdaode regs[11] = dsaf_read_dev(drv, GMAC_SHORT_RUNTS_THR_REG); 548511e6bc0Shuangdaode regs[12] = dsaf_read_dev(drv, GMAC_AN_NEG_STATE_REG); 549511e6bc0Shuangdaode regs[13] = dsaf_read_dev(drv, GMAC_TX_LOCAL_PAGE_REG); 550511e6bc0Shuangdaode regs[14] = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG); 551511e6bc0Shuangdaode regs[15] = dsaf_read_dev(drv, GMAC_REC_FILT_CONTROL_REG); 552511e6bc0Shuangdaode regs[16] = dsaf_read_dev(drv, GMAC_PTP_CONFIG_REG); 553511e6bc0Shuangdaode 554511e6bc0Shuangdaode /* rx static registers */ 555511e6bc0Shuangdaode regs[17] = dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_OK_REG); 556511e6bc0Shuangdaode regs[18] = dsaf_read_dev(drv, GMAC_RX_OCTETS_BAD_REG); 557511e6bc0Shuangdaode regs[19] = dsaf_read_dev(drv, GMAC_RX_UC_PKTS_REG); 558511e6bc0Shuangdaode regs[20] = dsaf_read_dev(drv, GMAC_RX_MC_PKTS_REG); 559511e6bc0Shuangdaode regs[21] = dsaf_read_dev(drv, GMAC_RX_BC_PKTS_REG); 560511e6bc0Shuangdaode regs[22] = dsaf_read_dev(drv, GMAC_RX_PKTS_64OCTETS_REG); 561511e6bc0Shuangdaode regs[23] = dsaf_read_dev(drv, GMAC_RX_PKTS_65TO127OCTETS_REG); 562511e6bc0Shuangdaode regs[24] = dsaf_read_dev(drv, GMAC_RX_PKTS_128TO255OCTETS_REG); 563511e6bc0Shuangdaode regs[25] = dsaf_read_dev(drv, GMAC_RX_PKTS_255TO511OCTETS_REG); 564511e6bc0Shuangdaode regs[26] = dsaf_read_dev(drv, GMAC_RX_PKTS_512TO1023OCTETS_REG); 565511e6bc0Shuangdaode regs[27] = dsaf_read_dev(drv, GMAC_RX_PKTS_1024TO1518OCTETS_REG); 566511e6bc0Shuangdaode regs[28] = dsaf_read_dev(drv, GMAC_RX_PKTS_1519TOMAXOCTETS_REG); 567511e6bc0Shuangdaode regs[29] = dsaf_read_dev(drv, GMAC_RX_FCS_ERRORS_REG); 568511e6bc0Shuangdaode regs[30] = dsaf_read_dev(drv, GMAC_RX_TAGGED_REG); 569511e6bc0Shuangdaode regs[31] = dsaf_read_dev(drv, GMAC_RX_DATA_ERR_REG); 570511e6bc0Shuangdaode regs[32] = dsaf_read_dev(drv, GMAC_RX_ALIGN_ERRORS_REG); 571511e6bc0Shuangdaode regs[33] = dsaf_read_dev(drv, GMAC_RX_LONG_ERRORS_REG); 572511e6bc0Shuangdaode regs[34] = dsaf_read_dev(drv, GMAC_RX_JABBER_ERRORS_REG); 573511e6bc0Shuangdaode regs[35] = dsaf_read_dev(drv, GMAC_RX_PAUSE_MACCTRL_FRAM_REG); 574511e6bc0Shuangdaode regs[36] = dsaf_read_dev(drv, GMAC_RX_UNKNOWN_MACCTRL_FRAM_REG); 575511e6bc0Shuangdaode regs[37] = dsaf_read_dev(drv, GMAC_RX_VERY_LONG_ERR_CNT_REG); 576511e6bc0Shuangdaode regs[38] = dsaf_read_dev(drv, GMAC_RX_RUNT_ERR_CNT_REG); 577511e6bc0Shuangdaode regs[39] = dsaf_read_dev(drv, GMAC_RX_SHORT_ERR_CNT_REG); 578511e6bc0Shuangdaode regs[40] = dsaf_read_dev(drv, GMAC_RX_FILT_PKT_CNT_REG); 579511e6bc0Shuangdaode regs[41] = dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_FILT_REG); 580511e6bc0Shuangdaode 581511e6bc0Shuangdaode /* tx static registers */ 582511e6bc0Shuangdaode regs[42] = dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_OK_REG); 583511e6bc0Shuangdaode regs[43] = dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_BAD_REG); 584511e6bc0Shuangdaode regs[44] = dsaf_read_dev(drv, GMAC_TX_UC_PKTS_REG); 585511e6bc0Shuangdaode regs[45] = dsaf_read_dev(drv, GMAC_TX_MC_PKTS_REG); 586511e6bc0Shuangdaode regs[46] = dsaf_read_dev(drv, GMAC_TX_BC_PKTS_REG); 587511e6bc0Shuangdaode regs[47] = dsaf_read_dev(drv, GMAC_TX_PKTS_64OCTETS_REG); 588511e6bc0Shuangdaode regs[48] = dsaf_read_dev(drv, GMAC_TX_PKTS_65TO127OCTETS_REG); 589511e6bc0Shuangdaode regs[49] = dsaf_read_dev(drv, GMAC_TX_PKTS_128TO255OCTETS_REG); 590511e6bc0Shuangdaode regs[50] = dsaf_read_dev(drv, GMAC_TX_PKTS_255TO511OCTETS_REG); 591511e6bc0Shuangdaode regs[51] = dsaf_read_dev(drv, GMAC_TX_PKTS_512TO1023OCTETS_REG); 592511e6bc0Shuangdaode regs[52] = dsaf_read_dev(drv, GMAC_TX_PKTS_1024TO1518OCTETS_REG); 593511e6bc0Shuangdaode regs[53] = dsaf_read_dev(drv, GMAC_TX_PKTS_1519TOMAXOCTETS_REG); 594511e6bc0Shuangdaode regs[54] = dsaf_read_dev(drv, GMAC_TX_EXCESSIVE_LENGTH_DROP_REG); 595511e6bc0Shuangdaode regs[55] = dsaf_read_dev(drv, GMAC_TX_UNDERRUN_REG); 596511e6bc0Shuangdaode regs[56] = dsaf_read_dev(drv, GMAC_TX_TAGGED_REG); 597511e6bc0Shuangdaode regs[57] = dsaf_read_dev(drv, GMAC_TX_CRC_ERROR_REG); 598511e6bc0Shuangdaode regs[58] = dsaf_read_dev(drv, GMAC_TX_PAUSE_FRAMES_REG); 599511e6bc0Shuangdaode 600511e6bc0Shuangdaode regs[59] = dsaf_read_dev(drv, GAMC_RX_MAX_FRAME); 601511e6bc0Shuangdaode regs[60] = dsaf_read_dev(drv, GMAC_LINE_LOOP_BACK_REG); 602511e6bc0Shuangdaode regs[61] = dsaf_read_dev(drv, GMAC_CF_CRC_STRIP_REG); 603511e6bc0Shuangdaode regs[62] = dsaf_read_dev(drv, GMAC_MODE_CHANGE_EN_REG); 604511e6bc0Shuangdaode regs[63] = dsaf_read_dev(drv, GMAC_SIXTEEN_BIT_CNTR_REG); 605511e6bc0Shuangdaode regs[64] = dsaf_read_dev(drv, GMAC_LD_LINK_COUNTER_REG); 606511e6bc0Shuangdaode regs[65] = dsaf_read_dev(drv, GMAC_LOOP_REG); 607511e6bc0Shuangdaode regs[66] = dsaf_read_dev(drv, GMAC_RECV_CONTROL_REG); 608511e6bc0Shuangdaode regs[67] = dsaf_read_dev(drv, GMAC_VLAN_CODE_REG); 609511e6bc0Shuangdaode regs[68] = dsaf_read_dev(drv, GMAC_RX_OVERRUN_CNT_REG); 610511e6bc0Shuangdaode regs[69] = dsaf_read_dev(drv, GMAC_RX_LENGTHFIELD_ERR_CNT_REG); 611511e6bc0Shuangdaode regs[70] = dsaf_read_dev(drv, GMAC_RX_FAIL_COMMA_CNT_REG); 612511e6bc0Shuangdaode 613511e6bc0Shuangdaode regs[71] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_0_REG); 614511e6bc0Shuangdaode regs[72] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_0_REG); 615511e6bc0Shuangdaode regs[73] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_1_REG); 616511e6bc0Shuangdaode regs[74] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_1_REG); 617511e6bc0Shuangdaode regs[75] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_2_REG); 618511e6bc0Shuangdaode regs[76] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG); 619511e6bc0Shuangdaode regs[77] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_3_REG); 620511e6bc0Shuangdaode regs[78] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_3_REG); 621511e6bc0Shuangdaode regs[79] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_4_REG); 622511e6bc0Shuangdaode regs[80] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_4_REG); 623511e6bc0Shuangdaode regs[81] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_5_REG); 624511e6bc0Shuangdaode regs[82] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_5_REG); 625511e6bc0Shuangdaode regs[83] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_MSK_0_REG); 626511e6bc0Shuangdaode regs[84] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_MSK_0_REG); 627511e6bc0Shuangdaode regs[85] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_MSK_1_REG); 628511e6bc0Shuangdaode regs[86] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_MSK_1_REG); 629511e6bc0Shuangdaode regs[87] = dsaf_read_dev(drv, GMAC_MAC_SKIP_LEN_REG); 630511e6bc0Shuangdaode regs[88] = dsaf_read_dev(drv, GMAC_TX_LOOP_PKT_PRI_REG); 631511e6bc0Shuangdaode 632511e6bc0Shuangdaode /* mark end of mac regs */ 633511e6bc0Shuangdaode for (i = 89; i < 96; i++) 634511e6bc0Shuangdaode regs[i] = 0xaaaaaaaa; 635511e6bc0Shuangdaode } 636511e6bc0Shuangdaode 637511e6bc0Shuangdaode static void hns_gmac_get_stats(void *mac_drv, u64 *data) 638511e6bc0Shuangdaode { 639511e6bc0Shuangdaode u32 i; 640511e6bc0Shuangdaode u64 *buf = data; 641511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 642511e6bc0Shuangdaode struct mac_hw_stats *hw_stats = NULL; 643511e6bc0Shuangdaode 644511e6bc0Shuangdaode hw_stats = &drv->mac_cb->hw_stats; 645511e6bc0Shuangdaode 646511e6bc0Shuangdaode for (i = 0; i < ARRAY_SIZE(g_gmac_stats_string); i++) { 647511e6bc0Shuangdaode buf[i] = DSAF_STATS_READ(hw_stats, 648511e6bc0Shuangdaode g_gmac_stats_string[i].offset); 649511e6bc0Shuangdaode } 650511e6bc0Shuangdaode } 651511e6bc0Shuangdaode 652511e6bc0Shuangdaode static void hns_gmac_get_strings(u32 stringset, u8 *data) 653511e6bc0Shuangdaode { 654511e6bc0Shuangdaode char *buff = (char *)data; 655511e6bc0Shuangdaode u32 i; 656511e6bc0Shuangdaode 657511e6bc0Shuangdaode if (stringset != ETH_SS_STATS) 658511e6bc0Shuangdaode return; 659511e6bc0Shuangdaode 660511e6bc0Shuangdaode for (i = 0; i < ARRAY_SIZE(g_gmac_stats_string); i++) { 6618d71397bSQianqian Xie snprintf(buff, ETH_GSTRING_LEN, "%s", 6628d71397bSQianqian Xie g_gmac_stats_string[i].desc); 663511e6bc0Shuangdaode buff = buff + ETH_GSTRING_LEN; 664511e6bc0Shuangdaode } 665511e6bc0Shuangdaode } 666511e6bc0Shuangdaode 667511e6bc0Shuangdaode static int hns_gmac_get_sset_count(int stringset) 668511e6bc0Shuangdaode { 669d61d263cSMatthias Brugger if (stringset == ETH_SS_STATS) 670511e6bc0Shuangdaode return ARRAY_SIZE(g_gmac_stats_string); 671511e6bc0Shuangdaode 672511e6bc0Shuangdaode return 0; 673511e6bc0Shuangdaode } 674511e6bc0Shuangdaode 675511e6bc0Shuangdaode static int hns_gmac_get_regs_count(void) 676511e6bc0Shuangdaode { 677511e6bc0Shuangdaode return ETH_GMAC_DUMP_NUM; 678511e6bc0Shuangdaode } 679511e6bc0Shuangdaode 680511e6bc0Shuangdaode void *hns_gmac_config(struct hns_mac_cb *mac_cb, struct mac_params *mac_param) 681511e6bc0Shuangdaode { 682511e6bc0Shuangdaode struct mac_driver *mac_drv; 683511e6bc0Shuangdaode 684511e6bc0Shuangdaode mac_drv = devm_kzalloc(mac_cb->dev, sizeof(*mac_drv), GFP_KERNEL); 685511e6bc0Shuangdaode if (!mac_drv) 686511e6bc0Shuangdaode return NULL; 687511e6bc0Shuangdaode 688511e6bc0Shuangdaode mac_drv->mac_init = hns_gmac_init; 689511e6bc0Shuangdaode mac_drv->mac_enable = hns_gmac_enable; 690511e6bc0Shuangdaode mac_drv->mac_disable = hns_gmac_disable; 691511e6bc0Shuangdaode mac_drv->mac_free = hns_gmac_free; 692511e6bc0Shuangdaode mac_drv->adjust_link = hns_gmac_adjust_link; 693511e6bc0Shuangdaode mac_drv->set_tx_auto_pause_frames = hns_gmac_set_tx_auto_pause_frames; 694511e6bc0Shuangdaode mac_drv->config_max_frame_length = hns_gmac_config_max_frame_length; 695511e6bc0Shuangdaode mac_drv->mac_pausefrm_cfg = hns_gmac_pause_frm_cfg; 696511e6bc0Shuangdaode 697511e6bc0Shuangdaode mac_drv->mac_id = mac_param->mac_id; 698511e6bc0Shuangdaode mac_drv->mac_mode = mac_param->mac_mode; 699511e6bc0Shuangdaode mac_drv->io_base = mac_param->vaddr; 700511e6bc0Shuangdaode mac_drv->dev = mac_param->dev; 701511e6bc0Shuangdaode mac_drv->mac_cb = mac_cb; 702511e6bc0Shuangdaode 703511e6bc0Shuangdaode mac_drv->set_mac_addr = hns_gmac_set_mac_addr; 704511e6bc0Shuangdaode mac_drv->set_an_mode = hns_gmac_config_an_mode; 705511e6bc0Shuangdaode mac_drv->config_loopback = hns_gmac_config_loopback; 706511e6bc0Shuangdaode mac_drv->config_pad_and_crc = hns_gmac_config_pad_and_crc; 707511e6bc0Shuangdaode mac_drv->config_half_duplex = hns_gmac_set_duplex_type; 708511e6bc0Shuangdaode mac_drv->set_rx_ignore_pause_frames = hns_gmac_set_rx_auto_pause_frames; 709511e6bc0Shuangdaode mac_drv->get_info = hns_gmac_get_info; 710511e6bc0Shuangdaode mac_drv->autoneg_stat = hns_gmac_autoneg_stat; 711511e6bc0Shuangdaode mac_drv->get_pause_enable = hns_gmac_get_pausefrm_cfg; 712511e6bc0Shuangdaode mac_drv->get_link_status = hns_gmac_get_link_status; 713511e6bc0Shuangdaode mac_drv->get_regs = hns_gmac_get_regs; 714511e6bc0Shuangdaode mac_drv->get_regs_count = hns_gmac_get_regs_count; 715511e6bc0Shuangdaode mac_drv->get_ethtool_stats = hns_gmac_get_stats; 716511e6bc0Shuangdaode mac_drv->get_sset_count = hns_gmac_get_sset_count; 717511e6bc0Shuangdaode mac_drv->get_strings = hns_gmac_get_strings; 718511e6bc0Shuangdaode mac_drv->update_stats = hns_gmac_update_stats; 719d5679849SKejian Yan mac_drv->set_promiscuous = hns_gmac_set_promisc; 720511e6bc0Shuangdaode 721511e6bc0Shuangdaode return (void *)mac_drv; 722511e6bc0Shuangdaode } 723