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)}, 20511e6bc0Shuangdaode {"gamc_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)}, 40511e6bc0Shuangdaode {"gmac_rx_filt_pkt", MAC_STATS_FIELD_OFF(rx_filter_bytes)}, 41511e6bc0Shuangdaode {"gmac_rx_octets_total_filt", MAC_STATS_FIELD_OFF(rx_filter_pkts)}, 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 89511e6bc0Shuangdaode /** 90511e6bc0Shuangdaode *hns_gmac_get_en - get port enable 91511e6bc0Shuangdaode *@mac_drv:mac device 92511e6bc0Shuangdaode *@rx:rx enable 93511e6bc0Shuangdaode *@tx:tx enable 94511e6bc0Shuangdaode */ 95511e6bc0Shuangdaode static void hns_gmac_get_en(void *mac_drv, u32 *rx, u32 *tx) 96511e6bc0Shuangdaode { 97511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 98511e6bc0Shuangdaode u32 porten; 99511e6bc0Shuangdaode 100511e6bc0Shuangdaode porten = dsaf_read_dev(drv, GMAC_PORT_EN_REG); 101511e6bc0Shuangdaode *tx = dsaf_get_bit(porten, GMAC_PORT_TX_EN_B); 102511e6bc0Shuangdaode *rx = dsaf_get_bit(porten, GMAC_PORT_RX_EN_B); 103511e6bc0Shuangdaode } 104511e6bc0Shuangdaode 105511e6bc0Shuangdaode static void hns_gmac_free(void *mac_drv) 106511e6bc0Shuangdaode { 107511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 108511e6bc0Shuangdaode struct dsaf_device *dsaf_dev 109511e6bc0Shuangdaode = (struct dsaf_device *)dev_get_drvdata(drv->dev); 110511e6bc0Shuangdaode 111511e6bc0Shuangdaode u32 mac_id = drv->mac_id; 112511e6bc0Shuangdaode 113511e6bc0Shuangdaode hns_dsaf_ge_srst_by_port(dsaf_dev, mac_id, 0); 114511e6bc0Shuangdaode } 115511e6bc0Shuangdaode 116511e6bc0Shuangdaode static void hns_gmac_set_tx_auto_pause_frames(void *mac_drv, u16 newval) 117511e6bc0Shuangdaode { 118511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 119511e6bc0Shuangdaode 120511e6bc0Shuangdaode dsaf_set_dev_field(drv, GMAC_FC_TX_TIMER_REG, GMAC_FC_TX_TIMER_M, 121511e6bc0Shuangdaode GMAC_FC_TX_TIMER_S, newval); 122511e6bc0Shuangdaode } 123511e6bc0Shuangdaode 124511e6bc0Shuangdaode static void hns_gmac_get_tx_auto_pause_frames(void *mac_drv, u16 *newval) 125511e6bc0Shuangdaode { 126511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 127511e6bc0Shuangdaode 128511e6bc0Shuangdaode *newval = dsaf_get_dev_field(drv, GMAC_FC_TX_TIMER_REG, 129511e6bc0Shuangdaode GMAC_FC_TX_TIMER_M, GMAC_FC_TX_TIMER_S); 130511e6bc0Shuangdaode } 131511e6bc0Shuangdaode 132511e6bc0Shuangdaode static void hns_gmac_set_rx_auto_pause_frames(void *mac_drv, u32 newval) 133511e6bc0Shuangdaode { 134511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 135511e6bc0Shuangdaode 136511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_PAUSE_EN_REG, 137511e6bc0Shuangdaode GMAC_PAUSE_EN_RX_FDFC_B, !!newval); 138511e6bc0Shuangdaode } 139511e6bc0Shuangdaode 140511e6bc0Shuangdaode static void hns_gmac_config_max_frame_length(void *mac_drv, u16 newval) 141511e6bc0Shuangdaode { 142511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 143511e6bc0Shuangdaode 144511e6bc0Shuangdaode dsaf_set_dev_field(drv, GMAC_MAX_FRM_SIZE_REG, GMAC_MAX_FRM_SIZE_M, 145511e6bc0Shuangdaode GMAC_MAX_FRM_SIZE_S, newval); 146511e6bc0Shuangdaode 147511e6bc0Shuangdaode dsaf_set_dev_field(drv, GAMC_RX_MAX_FRAME, GMAC_MAX_FRM_SIZE_M, 148511e6bc0Shuangdaode GMAC_MAX_FRM_SIZE_S, newval); 149511e6bc0Shuangdaode } 150511e6bc0Shuangdaode 151511e6bc0Shuangdaode static void hns_gmac_config_an_mode(void *mac_drv, u8 newval) 152511e6bc0Shuangdaode { 153511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 154511e6bc0Shuangdaode 155511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_TRANSMIT_CONTROL_REG, 156511e6bc0Shuangdaode GMAC_TX_AN_EN_B, !!newval); 157511e6bc0Shuangdaode } 158511e6bc0Shuangdaode 159511e6bc0Shuangdaode static void hns_gmac_tx_loop_pkt_dis(void *mac_drv) 160511e6bc0Shuangdaode { 161511e6bc0Shuangdaode u32 tx_loop_pkt_pri; 162511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 163511e6bc0Shuangdaode 164511e6bc0Shuangdaode tx_loop_pkt_pri = dsaf_read_dev(drv, GMAC_TX_LOOP_PKT_PRI_REG); 165511e6bc0Shuangdaode dsaf_set_bit(tx_loop_pkt_pri, GMAC_TX_LOOP_PKT_EN_B, 1); 166511e6bc0Shuangdaode dsaf_set_bit(tx_loop_pkt_pri, GMAC_TX_LOOP_PKT_HIG_PRI_B, 0); 167511e6bc0Shuangdaode dsaf_write_dev(drv, GMAC_TX_LOOP_PKT_PRI_REG, tx_loop_pkt_pri); 168511e6bc0Shuangdaode } 169511e6bc0Shuangdaode 170511e6bc0Shuangdaode static void hns_gmac_set_duplex_type(void *mac_drv, u8 newval) 171511e6bc0Shuangdaode { 172511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 173511e6bc0Shuangdaode 174511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_DUPLEX_TYPE_REG, 175511e6bc0Shuangdaode GMAC_DUPLEX_TYPE_B, !!newval); 176511e6bc0Shuangdaode } 177511e6bc0Shuangdaode 178511e6bc0Shuangdaode static void hns_gmac_get_duplex_type(void *mac_drv, 179511e6bc0Shuangdaode enum hns_gmac_duplex_mdoe *duplex_mode) 180511e6bc0Shuangdaode { 181511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 182511e6bc0Shuangdaode 183511e6bc0Shuangdaode *duplex_mode = (enum hns_gmac_duplex_mdoe)dsaf_get_dev_bit( 184511e6bc0Shuangdaode drv, GMAC_DUPLEX_TYPE_REG, GMAC_DUPLEX_TYPE_B); 185511e6bc0Shuangdaode } 186511e6bc0Shuangdaode 187511e6bc0Shuangdaode static void hns_gmac_get_port_mode(void *mac_drv, enum hns_port_mode *port_mode) 188511e6bc0Shuangdaode { 189511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 190511e6bc0Shuangdaode 191511e6bc0Shuangdaode *port_mode = (enum hns_port_mode)dsaf_get_dev_field( 192511e6bc0Shuangdaode drv, GMAC_PORT_MODE_REG, GMAC_PORT_MODE_M, GMAC_PORT_MODE_S); 193511e6bc0Shuangdaode } 194511e6bc0Shuangdaode 195511e6bc0Shuangdaode static void hns_gmac_port_mode_get(void *mac_drv, 196511e6bc0Shuangdaode struct hns_gmac_port_mode_cfg *port_mode) 197511e6bc0Shuangdaode { 198511e6bc0Shuangdaode u32 tx_ctrl; 199511e6bc0Shuangdaode u32 recv_ctrl; 200511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 201511e6bc0Shuangdaode 202511e6bc0Shuangdaode port_mode->port_mode = (enum hns_port_mode)dsaf_get_dev_field( 203511e6bc0Shuangdaode drv, GMAC_PORT_MODE_REG, GMAC_PORT_MODE_M, GMAC_PORT_MODE_S); 204511e6bc0Shuangdaode 205511e6bc0Shuangdaode tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG); 206511e6bc0Shuangdaode recv_ctrl = dsaf_read_dev(drv, GMAC_RECV_CONTROL_REG); 207511e6bc0Shuangdaode 208511e6bc0Shuangdaode port_mode->max_frm_size = 209511e6bc0Shuangdaode dsaf_get_dev_field(drv, GMAC_MAX_FRM_SIZE_REG, 210511e6bc0Shuangdaode GMAC_MAX_FRM_SIZE_M, GMAC_MAX_FRM_SIZE_S); 211511e6bc0Shuangdaode port_mode->short_runts_thr = 212511e6bc0Shuangdaode dsaf_get_dev_field(drv, GMAC_SHORT_RUNTS_THR_REG, 213511e6bc0Shuangdaode GMAC_SHORT_RUNTS_THR_M, 214511e6bc0Shuangdaode GMAC_SHORT_RUNTS_THR_S); 215511e6bc0Shuangdaode 216511e6bc0Shuangdaode port_mode->pad_enable = dsaf_get_bit(tx_ctrl, GMAC_TX_PAD_EN_B); 217511e6bc0Shuangdaode port_mode->crc_add = dsaf_get_bit(tx_ctrl, GMAC_TX_CRC_ADD_B); 218511e6bc0Shuangdaode port_mode->an_enable = dsaf_get_bit(tx_ctrl, GMAC_TX_AN_EN_B); 219511e6bc0Shuangdaode 220511e6bc0Shuangdaode port_mode->runt_pkt_en = 221511e6bc0Shuangdaode dsaf_get_bit(recv_ctrl, GMAC_RECV_CTRL_RUNT_PKT_EN_B); 222511e6bc0Shuangdaode port_mode->strip_pad_en = 223511e6bc0Shuangdaode dsaf_get_bit(recv_ctrl, GMAC_RECV_CTRL_STRIP_PAD_EN_B); 224511e6bc0Shuangdaode } 225511e6bc0Shuangdaode 226511e6bc0Shuangdaode static void hns_gmac_pause_frm_cfg(void *mac_drv, u32 rx_pause_en, 227511e6bc0Shuangdaode u32 tx_pause_en) 228511e6bc0Shuangdaode { 229511e6bc0Shuangdaode u32 pause_en; 230511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 231511e6bc0Shuangdaode 232511e6bc0Shuangdaode pause_en = dsaf_read_dev(drv, GMAC_PAUSE_EN_REG); 233511e6bc0Shuangdaode dsaf_set_bit(pause_en, GMAC_PAUSE_EN_RX_FDFC_B, !!rx_pause_en); 234511e6bc0Shuangdaode dsaf_set_bit(pause_en, GMAC_PAUSE_EN_TX_FDFC_B, !!tx_pause_en); 235511e6bc0Shuangdaode dsaf_write_dev(drv, GMAC_PAUSE_EN_REG, pause_en); 236511e6bc0Shuangdaode } 237511e6bc0Shuangdaode 238511e6bc0Shuangdaode static void hns_gmac_get_pausefrm_cfg(void *mac_drv, u32 *rx_pause_en, 239511e6bc0Shuangdaode u32 *tx_pause_en) 240511e6bc0Shuangdaode { 241511e6bc0Shuangdaode u32 pause_en; 242511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 243511e6bc0Shuangdaode 244511e6bc0Shuangdaode pause_en = dsaf_read_dev(drv, GMAC_PAUSE_EN_REG); 245511e6bc0Shuangdaode 246511e6bc0Shuangdaode *rx_pause_en = dsaf_get_bit(pause_en, GMAC_PAUSE_EN_RX_FDFC_B); 247511e6bc0Shuangdaode *tx_pause_en = dsaf_get_bit(pause_en, GMAC_PAUSE_EN_TX_FDFC_B); 248511e6bc0Shuangdaode } 249511e6bc0Shuangdaode 250511e6bc0Shuangdaode static int hns_gmac_adjust_link(void *mac_drv, enum mac_speed speed, 251511e6bc0Shuangdaode u32 full_duplex) 252511e6bc0Shuangdaode { 253511e6bc0Shuangdaode u32 tx_ctrl; 254511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 255511e6bc0Shuangdaode 256511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_DUPLEX_TYPE_REG, 257511e6bc0Shuangdaode GMAC_DUPLEX_TYPE_B, !!full_duplex); 258511e6bc0Shuangdaode 259511e6bc0Shuangdaode switch (speed) { 260511e6bc0Shuangdaode case MAC_SPEED_10: 261511e6bc0Shuangdaode dsaf_set_dev_field( 262511e6bc0Shuangdaode drv, GMAC_PORT_MODE_REG, 263511e6bc0Shuangdaode GMAC_PORT_MODE_M, GMAC_PORT_MODE_S, 0x6); 264511e6bc0Shuangdaode break; 265511e6bc0Shuangdaode case MAC_SPEED_100: 266511e6bc0Shuangdaode dsaf_set_dev_field( 267511e6bc0Shuangdaode drv, GMAC_PORT_MODE_REG, 268511e6bc0Shuangdaode GMAC_PORT_MODE_M, GMAC_PORT_MODE_S, 0x7); 269511e6bc0Shuangdaode break; 270511e6bc0Shuangdaode case MAC_SPEED_1000: 271511e6bc0Shuangdaode dsaf_set_dev_field( 272511e6bc0Shuangdaode drv, GMAC_PORT_MODE_REG, 273511e6bc0Shuangdaode GMAC_PORT_MODE_M, GMAC_PORT_MODE_S, 0x8); 274511e6bc0Shuangdaode break; 275511e6bc0Shuangdaode default: 276511e6bc0Shuangdaode dev_err(drv->dev, 277511e6bc0Shuangdaode "hns_gmac_adjust_link fail, speed%d mac%d\n", 278511e6bc0Shuangdaode speed, drv->mac_id); 279511e6bc0Shuangdaode return -EINVAL; 280511e6bc0Shuangdaode } 281511e6bc0Shuangdaode 282511e6bc0Shuangdaode tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG); 283511e6bc0Shuangdaode dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, 1); 284511e6bc0Shuangdaode dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, 1); 285511e6bc0Shuangdaode dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl); 286511e6bc0Shuangdaode 287511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG, 288511e6bc0Shuangdaode GMAC_MODE_CHANGE_EB_B, 1); 289511e6bc0Shuangdaode 290511e6bc0Shuangdaode return 0; 291511e6bc0Shuangdaode } 292511e6bc0Shuangdaode 293d5679849SKejian Yan static void hns_gmac_set_uc_match(void *mac_drv, u16 en) 294d5679849SKejian Yan { 295d5679849SKejian Yan struct mac_driver *drv = mac_drv; 296d5679849SKejian Yan 297d5679849SKejian Yan dsaf_set_dev_bit(drv, GMAC_REC_FILT_CONTROL_REG, 298d5679849SKejian Yan GMAC_UC_MATCH_EN_B, !en); 299d5679849SKejian Yan dsaf_set_dev_bit(drv, GMAC_STATION_ADDR_HIGH_2_REG, 300d5679849SKejian Yan GMAC_ADDR_EN_B, !en); 301d5679849SKejian Yan } 302d5679849SKejian Yan 303d5679849SKejian Yan static void hns_gmac_set_promisc(void *mac_drv, u8 en) 304d5679849SKejian Yan { 305d5679849SKejian Yan struct mac_driver *drv = mac_drv; 306d5679849SKejian Yan 307d5679849SKejian Yan if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG) 308d5679849SKejian Yan hns_gmac_set_uc_match(mac_drv, en); 309d5679849SKejian Yan } 310d5679849SKejian Yan 311511e6bc0Shuangdaode static void hns_gmac_init(void *mac_drv) 312511e6bc0Shuangdaode { 313511e6bc0Shuangdaode u32 port; 314511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 315511e6bc0Shuangdaode struct dsaf_device *dsaf_dev 316511e6bc0Shuangdaode = (struct dsaf_device *)dev_get_drvdata(drv->dev); 317511e6bc0Shuangdaode 318511e6bc0Shuangdaode port = drv->mac_id; 319511e6bc0Shuangdaode 320511e6bc0Shuangdaode hns_dsaf_ge_srst_by_port(dsaf_dev, port, 0); 321511e6bc0Shuangdaode mdelay(10); 322511e6bc0Shuangdaode hns_dsaf_ge_srst_by_port(dsaf_dev, port, 1); 323511e6bc0Shuangdaode mdelay(10); 324511e6bc0Shuangdaode hns_gmac_disable(mac_drv, MAC_COMM_MODE_RX_AND_TX); 325511e6bc0Shuangdaode hns_gmac_tx_loop_pkt_dis(mac_drv); 326d5679849SKejian Yan if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG) 327d5679849SKejian Yan hns_gmac_set_uc_match(mac_drv, 0); 328511e6bc0Shuangdaode } 329511e6bc0Shuangdaode 330511e6bc0Shuangdaode void hns_gmac_update_stats(void *mac_drv) 331511e6bc0Shuangdaode { 332511e6bc0Shuangdaode struct mac_hw_stats *hw_stats = NULL; 333511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 334511e6bc0Shuangdaode 335511e6bc0Shuangdaode hw_stats = &drv->mac_cb->hw_stats; 336511e6bc0Shuangdaode 337511e6bc0Shuangdaode /* RX */ 338511e6bc0Shuangdaode hw_stats->rx_good_bytes 339511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_OK_REG); 340511e6bc0Shuangdaode hw_stats->rx_bad_bytes 341511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_OCTETS_BAD_REG); 342511e6bc0Shuangdaode hw_stats->rx_uc_pkts += dsaf_read_dev(drv, GMAC_RX_UC_PKTS_REG); 343511e6bc0Shuangdaode hw_stats->rx_mc_pkts += dsaf_read_dev(drv, GMAC_RX_MC_PKTS_REG); 344511e6bc0Shuangdaode hw_stats->rx_bc_pkts += dsaf_read_dev(drv, GMAC_RX_BC_PKTS_REG); 345511e6bc0Shuangdaode hw_stats->rx_64bytes 346511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_64OCTETS_REG); 347511e6bc0Shuangdaode hw_stats->rx_65to127 348511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_65TO127OCTETS_REG); 349511e6bc0Shuangdaode hw_stats->rx_128to255 350511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_128TO255OCTETS_REG); 351511e6bc0Shuangdaode hw_stats->rx_256to511 352511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_255TO511OCTETS_REG); 353511e6bc0Shuangdaode hw_stats->rx_512to1023 354511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_512TO1023OCTETS_REG); 355511e6bc0Shuangdaode hw_stats->rx_1024to1518 356511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_1024TO1518OCTETS_REG); 357511e6bc0Shuangdaode hw_stats->rx_1519tomax 358511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PKTS_1519TOMAXOCTETS_REG); 359511e6bc0Shuangdaode hw_stats->rx_fcs_err += dsaf_read_dev(drv, GMAC_RX_FCS_ERRORS_REG); 360511e6bc0Shuangdaode hw_stats->rx_vlan_pkts += dsaf_read_dev(drv, GMAC_RX_TAGGED_REG); 361511e6bc0Shuangdaode hw_stats->rx_data_err += dsaf_read_dev(drv, GMAC_RX_DATA_ERR_REG); 362511e6bc0Shuangdaode hw_stats->rx_align_err 363511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_ALIGN_ERRORS_REG); 364511e6bc0Shuangdaode hw_stats->rx_oversize 365511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_LONG_ERRORS_REG); 366511e6bc0Shuangdaode hw_stats->rx_jabber_err 367511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_JABBER_ERRORS_REG); 368511e6bc0Shuangdaode hw_stats->rx_pfc_tc0 369511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_PAUSE_MACCTRL_FRAM_REG); 370511e6bc0Shuangdaode hw_stats->rx_unknown_ctrl 371511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_UNKNOWN_MACCTRL_FRAM_REG); 372511e6bc0Shuangdaode hw_stats->rx_long_err 373511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_VERY_LONG_ERR_CNT_REG); 374511e6bc0Shuangdaode hw_stats->rx_minto64 375511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_RUNT_ERR_CNT_REG); 376511e6bc0Shuangdaode hw_stats->rx_under_min 377511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_SHORT_ERR_CNT_REG); 378511e6bc0Shuangdaode hw_stats->rx_filter_pkts 379511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_FILT_PKT_CNT_REG); 380511e6bc0Shuangdaode hw_stats->rx_filter_bytes 381511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_FILT_REG); 382511e6bc0Shuangdaode hw_stats->rx_fifo_overrun_err 383511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_OVERRUN_CNT_REG); 384511e6bc0Shuangdaode hw_stats->rx_len_err 385511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_LENGTHFIELD_ERR_CNT_REG); 386511e6bc0Shuangdaode hw_stats->rx_comma_err 387511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_RX_FAIL_COMMA_CNT_REG); 388511e6bc0Shuangdaode 389511e6bc0Shuangdaode /* TX */ 390511e6bc0Shuangdaode hw_stats->tx_good_bytes 391511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_OK_REG); 392511e6bc0Shuangdaode hw_stats->tx_bad_bytes 393511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_BAD_REG); 394511e6bc0Shuangdaode hw_stats->tx_uc_pkts += dsaf_read_dev(drv, GMAC_TX_UC_PKTS_REG); 395511e6bc0Shuangdaode hw_stats->tx_mc_pkts += dsaf_read_dev(drv, GMAC_TX_MC_PKTS_REG); 396511e6bc0Shuangdaode hw_stats->tx_bc_pkts += dsaf_read_dev(drv, GMAC_TX_BC_PKTS_REG); 397511e6bc0Shuangdaode hw_stats->tx_64bytes 398511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_64OCTETS_REG); 399511e6bc0Shuangdaode hw_stats->tx_65to127 400511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_65TO127OCTETS_REG); 401511e6bc0Shuangdaode hw_stats->tx_128to255 402511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_128TO255OCTETS_REG); 403511e6bc0Shuangdaode hw_stats->tx_256to511 404511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_255TO511OCTETS_REG); 405511e6bc0Shuangdaode hw_stats->tx_512to1023 406511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_512TO1023OCTETS_REG); 407511e6bc0Shuangdaode hw_stats->tx_1024to1518 408511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_1024TO1518OCTETS_REG); 409511e6bc0Shuangdaode hw_stats->tx_1519tomax 410511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PKTS_1519TOMAXOCTETS_REG); 411511e6bc0Shuangdaode hw_stats->tx_jabber_err 412511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_EXCESSIVE_LENGTH_DROP_REG); 413511e6bc0Shuangdaode hw_stats->tx_underrun_err 414511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_UNDERRUN_REG); 415511e6bc0Shuangdaode hw_stats->tx_vlan += dsaf_read_dev(drv, GMAC_TX_TAGGED_REG); 416511e6bc0Shuangdaode hw_stats->tx_crc_err += dsaf_read_dev(drv, GMAC_TX_CRC_ERROR_REG); 417511e6bc0Shuangdaode hw_stats->tx_pfc_tc0 418511e6bc0Shuangdaode += dsaf_read_dev(drv, GMAC_TX_PAUSE_FRAMES_REG); 419511e6bc0Shuangdaode } 420511e6bc0Shuangdaode 421511e6bc0Shuangdaode static void hns_gmac_set_mac_addr(void *mac_drv, char *mac_addr) 422511e6bc0Shuangdaode { 423511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 424511e6bc0Shuangdaode 425511e6bc0Shuangdaode u32 high_val = mac_addr[1] | (mac_addr[0] << 8); 426511e6bc0Shuangdaode 427511e6bc0Shuangdaode u32 low_val = mac_addr[5] | (mac_addr[4] << 8) 428511e6bc0Shuangdaode | (mac_addr[3] << 16) | (mac_addr[2] << 24); 429d5679849SKejian Yan 430d5679849SKejian Yan u32 val = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG); 431d5679849SKejian Yan u32 sta_addr_en = dsaf_get_bit(val, GMAC_ADDR_EN_B); 432d5679849SKejian Yan 433511e6bc0Shuangdaode dsaf_write_dev(drv, GMAC_STATION_ADDR_LOW_2_REG, low_val); 434d5679849SKejian Yan dsaf_write_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG, 435d5679849SKejian Yan high_val | (sta_addr_en << GMAC_ADDR_EN_B)); 436511e6bc0Shuangdaode } 437511e6bc0Shuangdaode 438511e6bc0Shuangdaode static int hns_gmac_config_loopback(void *mac_drv, enum hnae_loop loop_mode, 439511e6bc0Shuangdaode u8 enable) 440511e6bc0Shuangdaode { 441511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 442511e6bc0Shuangdaode 443511e6bc0Shuangdaode switch (loop_mode) { 444511e6bc0Shuangdaode case MAC_INTERNALLOOP_MAC: 445511e6bc0Shuangdaode dsaf_set_dev_bit(drv, GMAC_LOOP_REG, GMAC_LP_REG_CF2MI_LP_EN_B, 446511e6bc0Shuangdaode !!enable); 447511e6bc0Shuangdaode break; 448511e6bc0Shuangdaode default: 449511e6bc0Shuangdaode dev_err(drv->dev, "loop_mode error\n"); 450511e6bc0Shuangdaode return -EINVAL; 451511e6bc0Shuangdaode } 452511e6bc0Shuangdaode 453511e6bc0Shuangdaode return 0; 454511e6bc0Shuangdaode } 455511e6bc0Shuangdaode 456511e6bc0Shuangdaode static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval) 457511e6bc0Shuangdaode { 458511e6bc0Shuangdaode u32 tx_ctrl; 459511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 460511e6bc0Shuangdaode 461511e6bc0Shuangdaode tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG); 462511e6bc0Shuangdaode dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval); 463511e6bc0Shuangdaode dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval); 464511e6bc0Shuangdaode dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl); 465511e6bc0Shuangdaode } 466511e6bc0Shuangdaode 467511e6bc0Shuangdaode static void hns_gmac_get_id(void *mac_drv, u8 *mac_id) 468511e6bc0Shuangdaode { 469511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 470511e6bc0Shuangdaode 471511e6bc0Shuangdaode *mac_id = drv->mac_id; 472511e6bc0Shuangdaode } 473511e6bc0Shuangdaode 474511e6bc0Shuangdaode static void hns_gmac_get_info(void *mac_drv, struct mac_info *mac_info) 475511e6bc0Shuangdaode { 476511e6bc0Shuangdaode enum hns_gmac_duplex_mdoe duplex; 477511e6bc0Shuangdaode enum hns_port_mode speed; 478511e6bc0Shuangdaode u32 rx_pause; 479511e6bc0Shuangdaode u32 tx_pause; 480511e6bc0Shuangdaode u32 rx; 481511e6bc0Shuangdaode u32 tx; 482511e6bc0Shuangdaode u16 fc_tx_timer; 483511e6bc0Shuangdaode struct hns_gmac_port_mode_cfg port_mode = { GMAC_10M_MII, 0 }; 484511e6bc0Shuangdaode 485511e6bc0Shuangdaode hns_gmac_port_mode_get(mac_drv, &port_mode); 486511e6bc0Shuangdaode mac_info->pad_and_crc_en = port_mode.crc_add && port_mode.pad_enable; 487511e6bc0Shuangdaode mac_info->auto_neg = port_mode.an_enable; 488511e6bc0Shuangdaode 489511e6bc0Shuangdaode hns_gmac_get_tx_auto_pause_frames(mac_drv, &fc_tx_timer); 490511e6bc0Shuangdaode mac_info->tx_pause_time = fc_tx_timer; 491511e6bc0Shuangdaode 492511e6bc0Shuangdaode hns_gmac_get_en(mac_drv, &rx, &tx); 493511e6bc0Shuangdaode mac_info->port_en = rx && tx; 494511e6bc0Shuangdaode 495511e6bc0Shuangdaode hns_gmac_get_duplex_type(mac_drv, &duplex); 496511e6bc0Shuangdaode mac_info->duplex = duplex; 497511e6bc0Shuangdaode 498511e6bc0Shuangdaode hns_gmac_get_port_mode(mac_drv, &speed); 499511e6bc0Shuangdaode switch (speed) { 500511e6bc0Shuangdaode case GMAC_10M_SGMII: 501511e6bc0Shuangdaode mac_info->speed = MAC_SPEED_10; 502511e6bc0Shuangdaode break; 503511e6bc0Shuangdaode case GMAC_100M_SGMII: 504511e6bc0Shuangdaode mac_info->speed = MAC_SPEED_100; 505511e6bc0Shuangdaode break; 506511e6bc0Shuangdaode case GMAC_1000M_SGMII: 507511e6bc0Shuangdaode mac_info->speed = MAC_SPEED_1000; 508511e6bc0Shuangdaode break; 509511e6bc0Shuangdaode default: 510511e6bc0Shuangdaode mac_info->speed = 0; 511511e6bc0Shuangdaode break; 512511e6bc0Shuangdaode } 513511e6bc0Shuangdaode 514511e6bc0Shuangdaode hns_gmac_get_pausefrm_cfg(mac_drv, &rx_pause, &tx_pause); 515511e6bc0Shuangdaode mac_info->rx_pause_en = rx_pause; 516511e6bc0Shuangdaode mac_info->tx_pause_en = tx_pause; 517511e6bc0Shuangdaode } 518511e6bc0Shuangdaode 519511e6bc0Shuangdaode static void hns_gmac_autoneg_stat(void *mac_drv, u32 *enable) 520511e6bc0Shuangdaode { 521511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 522511e6bc0Shuangdaode 523511e6bc0Shuangdaode *enable = dsaf_get_dev_bit(drv, GMAC_TRANSMIT_CONTROL_REG, 524511e6bc0Shuangdaode GMAC_TX_AN_EN_B); 525511e6bc0Shuangdaode } 526511e6bc0Shuangdaode 527511e6bc0Shuangdaode static void hns_gmac_get_link_status(void *mac_drv, u32 *link_stat) 528511e6bc0Shuangdaode { 529511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 530511e6bc0Shuangdaode 531511e6bc0Shuangdaode *link_stat = dsaf_get_dev_bit(drv, GMAC_AN_NEG_STATE_REG, 532511e6bc0Shuangdaode GMAC_AN_NEG_STAT_RX_SYNC_OK_B); 533511e6bc0Shuangdaode } 534511e6bc0Shuangdaode 535511e6bc0Shuangdaode static void hns_gmac_get_regs(void *mac_drv, void *data) 536511e6bc0Shuangdaode { 537511e6bc0Shuangdaode u32 *regs = data; 538511e6bc0Shuangdaode int i; 539511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 540511e6bc0Shuangdaode 541511e6bc0Shuangdaode /* base config registers */ 542511e6bc0Shuangdaode regs[0] = dsaf_read_dev(drv, GMAC_DUPLEX_TYPE_REG); 543511e6bc0Shuangdaode regs[1] = dsaf_read_dev(drv, GMAC_FD_FC_TYPE_REG); 544511e6bc0Shuangdaode regs[2] = dsaf_read_dev(drv, GMAC_FC_TX_TIMER_REG); 545511e6bc0Shuangdaode regs[3] = dsaf_read_dev(drv, GMAC_FD_FC_ADDR_LOW_REG); 546511e6bc0Shuangdaode regs[4] = dsaf_read_dev(drv, GMAC_FD_FC_ADDR_HIGH_REG); 547511e6bc0Shuangdaode regs[5] = dsaf_read_dev(drv, GMAC_IPG_TX_TIMER_REG); 548511e6bc0Shuangdaode regs[6] = dsaf_read_dev(drv, GMAC_PAUSE_THR_REG); 549511e6bc0Shuangdaode regs[7] = dsaf_read_dev(drv, GMAC_MAX_FRM_SIZE_REG); 550511e6bc0Shuangdaode regs[8] = dsaf_read_dev(drv, GMAC_PORT_MODE_REG); 551511e6bc0Shuangdaode regs[9] = dsaf_read_dev(drv, GMAC_PORT_EN_REG); 552511e6bc0Shuangdaode regs[10] = dsaf_read_dev(drv, GMAC_PAUSE_EN_REG); 553511e6bc0Shuangdaode regs[11] = dsaf_read_dev(drv, GMAC_SHORT_RUNTS_THR_REG); 554511e6bc0Shuangdaode regs[12] = dsaf_read_dev(drv, GMAC_AN_NEG_STATE_REG); 555511e6bc0Shuangdaode regs[13] = dsaf_read_dev(drv, GMAC_TX_LOCAL_PAGE_REG); 556511e6bc0Shuangdaode regs[14] = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG); 557511e6bc0Shuangdaode regs[15] = dsaf_read_dev(drv, GMAC_REC_FILT_CONTROL_REG); 558511e6bc0Shuangdaode regs[16] = dsaf_read_dev(drv, GMAC_PTP_CONFIG_REG); 559511e6bc0Shuangdaode 560511e6bc0Shuangdaode /* rx static registers */ 561511e6bc0Shuangdaode regs[17] = dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_OK_REG); 562511e6bc0Shuangdaode regs[18] = dsaf_read_dev(drv, GMAC_RX_OCTETS_BAD_REG); 563511e6bc0Shuangdaode regs[19] = dsaf_read_dev(drv, GMAC_RX_UC_PKTS_REG); 564511e6bc0Shuangdaode regs[20] = dsaf_read_dev(drv, GMAC_RX_MC_PKTS_REG); 565511e6bc0Shuangdaode regs[21] = dsaf_read_dev(drv, GMAC_RX_BC_PKTS_REG); 566511e6bc0Shuangdaode regs[22] = dsaf_read_dev(drv, GMAC_RX_PKTS_64OCTETS_REG); 567511e6bc0Shuangdaode regs[23] = dsaf_read_dev(drv, GMAC_RX_PKTS_65TO127OCTETS_REG); 568511e6bc0Shuangdaode regs[24] = dsaf_read_dev(drv, GMAC_RX_PKTS_128TO255OCTETS_REG); 569511e6bc0Shuangdaode regs[25] = dsaf_read_dev(drv, GMAC_RX_PKTS_255TO511OCTETS_REG); 570511e6bc0Shuangdaode regs[26] = dsaf_read_dev(drv, GMAC_RX_PKTS_512TO1023OCTETS_REG); 571511e6bc0Shuangdaode regs[27] = dsaf_read_dev(drv, GMAC_RX_PKTS_1024TO1518OCTETS_REG); 572511e6bc0Shuangdaode regs[28] = dsaf_read_dev(drv, GMAC_RX_PKTS_1519TOMAXOCTETS_REG); 573511e6bc0Shuangdaode regs[29] = dsaf_read_dev(drv, GMAC_RX_FCS_ERRORS_REG); 574511e6bc0Shuangdaode regs[30] = dsaf_read_dev(drv, GMAC_RX_TAGGED_REG); 575511e6bc0Shuangdaode regs[31] = dsaf_read_dev(drv, GMAC_RX_DATA_ERR_REG); 576511e6bc0Shuangdaode regs[32] = dsaf_read_dev(drv, GMAC_RX_ALIGN_ERRORS_REG); 577511e6bc0Shuangdaode regs[33] = dsaf_read_dev(drv, GMAC_RX_LONG_ERRORS_REG); 578511e6bc0Shuangdaode regs[34] = dsaf_read_dev(drv, GMAC_RX_JABBER_ERRORS_REG); 579511e6bc0Shuangdaode regs[35] = dsaf_read_dev(drv, GMAC_RX_PAUSE_MACCTRL_FRAM_REG); 580511e6bc0Shuangdaode regs[36] = dsaf_read_dev(drv, GMAC_RX_UNKNOWN_MACCTRL_FRAM_REG); 581511e6bc0Shuangdaode regs[37] = dsaf_read_dev(drv, GMAC_RX_VERY_LONG_ERR_CNT_REG); 582511e6bc0Shuangdaode regs[38] = dsaf_read_dev(drv, GMAC_RX_RUNT_ERR_CNT_REG); 583511e6bc0Shuangdaode regs[39] = dsaf_read_dev(drv, GMAC_RX_SHORT_ERR_CNT_REG); 584511e6bc0Shuangdaode regs[40] = dsaf_read_dev(drv, GMAC_RX_FILT_PKT_CNT_REG); 585511e6bc0Shuangdaode regs[41] = dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_FILT_REG); 586511e6bc0Shuangdaode 587511e6bc0Shuangdaode /* tx static registers */ 588511e6bc0Shuangdaode regs[42] = dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_OK_REG); 589511e6bc0Shuangdaode regs[43] = dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_BAD_REG); 590511e6bc0Shuangdaode regs[44] = dsaf_read_dev(drv, GMAC_TX_UC_PKTS_REG); 591511e6bc0Shuangdaode regs[45] = dsaf_read_dev(drv, GMAC_TX_MC_PKTS_REG); 592511e6bc0Shuangdaode regs[46] = dsaf_read_dev(drv, GMAC_TX_BC_PKTS_REG); 593511e6bc0Shuangdaode regs[47] = dsaf_read_dev(drv, GMAC_TX_PKTS_64OCTETS_REG); 594511e6bc0Shuangdaode regs[48] = dsaf_read_dev(drv, GMAC_TX_PKTS_65TO127OCTETS_REG); 595511e6bc0Shuangdaode regs[49] = dsaf_read_dev(drv, GMAC_TX_PKTS_128TO255OCTETS_REG); 596511e6bc0Shuangdaode regs[50] = dsaf_read_dev(drv, GMAC_TX_PKTS_255TO511OCTETS_REG); 597511e6bc0Shuangdaode regs[51] = dsaf_read_dev(drv, GMAC_TX_PKTS_512TO1023OCTETS_REG); 598511e6bc0Shuangdaode regs[52] = dsaf_read_dev(drv, GMAC_TX_PKTS_1024TO1518OCTETS_REG); 599511e6bc0Shuangdaode regs[53] = dsaf_read_dev(drv, GMAC_TX_PKTS_1519TOMAXOCTETS_REG); 600511e6bc0Shuangdaode regs[54] = dsaf_read_dev(drv, GMAC_TX_EXCESSIVE_LENGTH_DROP_REG); 601511e6bc0Shuangdaode regs[55] = dsaf_read_dev(drv, GMAC_TX_UNDERRUN_REG); 602511e6bc0Shuangdaode regs[56] = dsaf_read_dev(drv, GMAC_TX_TAGGED_REG); 603511e6bc0Shuangdaode regs[57] = dsaf_read_dev(drv, GMAC_TX_CRC_ERROR_REG); 604511e6bc0Shuangdaode regs[58] = dsaf_read_dev(drv, GMAC_TX_PAUSE_FRAMES_REG); 605511e6bc0Shuangdaode 606511e6bc0Shuangdaode regs[59] = dsaf_read_dev(drv, GAMC_RX_MAX_FRAME); 607511e6bc0Shuangdaode regs[60] = dsaf_read_dev(drv, GMAC_LINE_LOOP_BACK_REG); 608511e6bc0Shuangdaode regs[61] = dsaf_read_dev(drv, GMAC_CF_CRC_STRIP_REG); 609511e6bc0Shuangdaode regs[62] = dsaf_read_dev(drv, GMAC_MODE_CHANGE_EN_REG); 610511e6bc0Shuangdaode regs[63] = dsaf_read_dev(drv, GMAC_SIXTEEN_BIT_CNTR_REG); 611511e6bc0Shuangdaode regs[64] = dsaf_read_dev(drv, GMAC_LD_LINK_COUNTER_REG); 612511e6bc0Shuangdaode regs[65] = dsaf_read_dev(drv, GMAC_LOOP_REG); 613511e6bc0Shuangdaode regs[66] = dsaf_read_dev(drv, GMAC_RECV_CONTROL_REG); 614511e6bc0Shuangdaode regs[67] = dsaf_read_dev(drv, GMAC_VLAN_CODE_REG); 615511e6bc0Shuangdaode regs[68] = dsaf_read_dev(drv, GMAC_RX_OVERRUN_CNT_REG); 616511e6bc0Shuangdaode regs[69] = dsaf_read_dev(drv, GMAC_RX_LENGTHFIELD_ERR_CNT_REG); 617511e6bc0Shuangdaode regs[70] = dsaf_read_dev(drv, GMAC_RX_FAIL_COMMA_CNT_REG); 618511e6bc0Shuangdaode 619511e6bc0Shuangdaode regs[71] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_0_REG); 620511e6bc0Shuangdaode regs[72] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_0_REG); 621511e6bc0Shuangdaode regs[73] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_1_REG); 622511e6bc0Shuangdaode regs[74] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_1_REG); 623511e6bc0Shuangdaode regs[75] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_2_REG); 624511e6bc0Shuangdaode regs[76] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG); 625511e6bc0Shuangdaode regs[77] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_3_REG); 626511e6bc0Shuangdaode regs[78] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_3_REG); 627511e6bc0Shuangdaode regs[79] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_4_REG); 628511e6bc0Shuangdaode regs[80] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_4_REG); 629511e6bc0Shuangdaode regs[81] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_5_REG); 630511e6bc0Shuangdaode regs[82] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_5_REG); 631511e6bc0Shuangdaode regs[83] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_MSK_0_REG); 632511e6bc0Shuangdaode regs[84] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_MSK_0_REG); 633511e6bc0Shuangdaode regs[85] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_MSK_1_REG); 634511e6bc0Shuangdaode regs[86] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_MSK_1_REG); 635511e6bc0Shuangdaode regs[87] = dsaf_read_dev(drv, GMAC_MAC_SKIP_LEN_REG); 636511e6bc0Shuangdaode regs[88] = dsaf_read_dev(drv, GMAC_TX_LOOP_PKT_PRI_REG); 637511e6bc0Shuangdaode 638511e6bc0Shuangdaode /* mark end of mac regs */ 639511e6bc0Shuangdaode for (i = 89; i < 96; i++) 640511e6bc0Shuangdaode regs[i] = 0xaaaaaaaa; 641511e6bc0Shuangdaode } 642511e6bc0Shuangdaode 643511e6bc0Shuangdaode static void hns_gmac_get_stats(void *mac_drv, u64 *data) 644511e6bc0Shuangdaode { 645511e6bc0Shuangdaode u32 i; 646511e6bc0Shuangdaode u64 *buf = data; 647511e6bc0Shuangdaode struct mac_driver *drv = (struct mac_driver *)mac_drv; 648511e6bc0Shuangdaode struct mac_hw_stats *hw_stats = NULL; 649511e6bc0Shuangdaode 650511e6bc0Shuangdaode hw_stats = &drv->mac_cb->hw_stats; 651511e6bc0Shuangdaode 652511e6bc0Shuangdaode for (i = 0; i < ARRAY_SIZE(g_gmac_stats_string); i++) { 653511e6bc0Shuangdaode buf[i] = DSAF_STATS_READ(hw_stats, 654511e6bc0Shuangdaode g_gmac_stats_string[i].offset); 655511e6bc0Shuangdaode } 656511e6bc0Shuangdaode } 657511e6bc0Shuangdaode 658511e6bc0Shuangdaode static void hns_gmac_get_strings(u32 stringset, u8 *data) 659511e6bc0Shuangdaode { 660511e6bc0Shuangdaode char *buff = (char *)data; 661511e6bc0Shuangdaode u32 i; 662511e6bc0Shuangdaode 663511e6bc0Shuangdaode if (stringset != ETH_SS_STATS) 664511e6bc0Shuangdaode return; 665511e6bc0Shuangdaode 666511e6bc0Shuangdaode for (i = 0; i < ARRAY_SIZE(g_gmac_stats_string); i++) { 6678d71397bSQianqian Xie snprintf(buff, ETH_GSTRING_LEN, "%s", 6688d71397bSQianqian Xie g_gmac_stats_string[i].desc); 669511e6bc0Shuangdaode buff = buff + ETH_GSTRING_LEN; 670511e6bc0Shuangdaode } 671511e6bc0Shuangdaode } 672511e6bc0Shuangdaode 673511e6bc0Shuangdaode static int hns_gmac_get_sset_count(int stringset) 674511e6bc0Shuangdaode { 675511e6bc0Shuangdaode if (stringset == ETH_SS_STATS) 676511e6bc0Shuangdaode return ARRAY_SIZE(g_gmac_stats_string); 677511e6bc0Shuangdaode 678511e6bc0Shuangdaode return 0; 679511e6bc0Shuangdaode } 680511e6bc0Shuangdaode 681511e6bc0Shuangdaode static int hns_gmac_get_regs_count(void) 682511e6bc0Shuangdaode { 683511e6bc0Shuangdaode return ETH_GMAC_DUMP_NUM; 684511e6bc0Shuangdaode } 685511e6bc0Shuangdaode 686511e6bc0Shuangdaode void *hns_gmac_config(struct hns_mac_cb *mac_cb, struct mac_params *mac_param) 687511e6bc0Shuangdaode { 688511e6bc0Shuangdaode struct mac_driver *mac_drv; 689511e6bc0Shuangdaode 690511e6bc0Shuangdaode mac_drv = devm_kzalloc(mac_cb->dev, sizeof(*mac_drv), GFP_KERNEL); 691511e6bc0Shuangdaode if (!mac_drv) 692511e6bc0Shuangdaode return NULL; 693511e6bc0Shuangdaode 694511e6bc0Shuangdaode mac_drv->mac_init = hns_gmac_init; 695511e6bc0Shuangdaode mac_drv->mac_enable = hns_gmac_enable; 696511e6bc0Shuangdaode mac_drv->mac_disable = hns_gmac_disable; 697511e6bc0Shuangdaode mac_drv->mac_free = hns_gmac_free; 698511e6bc0Shuangdaode mac_drv->adjust_link = hns_gmac_adjust_link; 699511e6bc0Shuangdaode mac_drv->set_tx_auto_pause_frames = hns_gmac_set_tx_auto_pause_frames; 700511e6bc0Shuangdaode mac_drv->config_max_frame_length = hns_gmac_config_max_frame_length; 701511e6bc0Shuangdaode mac_drv->mac_pausefrm_cfg = hns_gmac_pause_frm_cfg; 702511e6bc0Shuangdaode 703511e6bc0Shuangdaode mac_drv->mac_id = mac_param->mac_id; 704511e6bc0Shuangdaode mac_drv->mac_mode = mac_param->mac_mode; 705511e6bc0Shuangdaode mac_drv->io_base = mac_param->vaddr; 706511e6bc0Shuangdaode mac_drv->dev = mac_param->dev; 707511e6bc0Shuangdaode mac_drv->mac_cb = mac_cb; 708511e6bc0Shuangdaode 709511e6bc0Shuangdaode mac_drv->set_mac_addr = hns_gmac_set_mac_addr; 710511e6bc0Shuangdaode mac_drv->set_an_mode = hns_gmac_config_an_mode; 711511e6bc0Shuangdaode mac_drv->config_loopback = hns_gmac_config_loopback; 712511e6bc0Shuangdaode mac_drv->config_pad_and_crc = hns_gmac_config_pad_and_crc; 713511e6bc0Shuangdaode mac_drv->config_half_duplex = hns_gmac_set_duplex_type; 714511e6bc0Shuangdaode mac_drv->set_rx_ignore_pause_frames = hns_gmac_set_rx_auto_pause_frames; 715511e6bc0Shuangdaode mac_drv->mac_get_id = hns_gmac_get_id; 716511e6bc0Shuangdaode mac_drv->get_info = hns_gmac_get_info; 717511e6bc0Shuangdaode mac_drv->autoneg_stat = hns_gmac_autoneg_stat; 718511e6bc0Shuangdaode mac_drv->get_pause_enable = hns_gmac_get_pausefrm_cfg; 719511e6bc0Shuangdaode mac_drv->get_link_status = hns_gmac_get_link_status; 720511e6bc0Shuangdaode mac_drv->get_regs = hns_gmac_get_regs; 721511e6bc0Shuangdaode mac_drv->get_regs_count = hns_gmac_get_regs_count; 722511e6bc0Shuangdaode mac_drv->get_ethtool_stats = hns_gmac_get_stats; 723511e6bc0Shuangdaode mac_drv->get_sset_count = hns_gmac_get_sset_count; 724511e6bc0Shuangdaode mac_drv->get_strings = hns_gmac_get_strings; 725511e6bc0Shuangdaode mac_drv->update_stats = hns_gmac_update_stats; 726d5679849SKejian Yan mac_drv->set_promiscuous = hns_gmac_set_promisc; 727511e6bc0Shuangdaode 728511e6bc0Shuangdaode return (void *)mac_drv; 729511e6bc0Shuangdaode } 730