1e8d13548SJijie Shao // SPDX-License-Identifier: GPL-2.0+ 2e8d13548SJijie Shao // Copyright (c) 2024 Hisilicon Limited. 3e8d13548SJijie Shao 4e8d13548SJijie Shao #include <linux/ethtool.h> 5e8d13548SJijie Shao #include <linux/phy.h> 6*51574da8SJijie Shao #include "hbg_common.h" 7e8d13548SJijie Shao #include "hbg_ethtool.h" 8*51574da8SJijie Shao #include "hbg_hw.h" 9*51574da8SJijie Shao 10*51574da8SJijie Shao enum hbg_reg_dump_type { 11*51574da8SJijie Shao HBG_DUMP_REG_TYPE_SPEC = 0, 12*51574da8SJijie Shao HBG_DUMP_REG_TYPE_MDIO, 13*51574da8SJijie Shao HBG_DUMP_REG_TYPE_GMAC, 14*51574da8SJijie Shao HBG_DUMP_REG_TYPE_PCU, 15*51574da8SJijie Shao }; 16*51574da8SJijie Shao 17*51574da8SJijie Shao struct hbg_reg_info { 18*51574da8SJijie Shao u32 type; 19*51574da8SJijie Shao u32 offset; 20*51574da8SJijie Shao u32 val; 21*51574da8SJijie Shao }; 22*51574da8SJijie Shao 23*51574da8SJijie Shao #define HBG_DUMP_SPEC_I(offset) {HBG_DUMP_REG_TYPE_SPEC, offset, 0} 24*51574da8SJijie Shao #define HBG_DUMP_MDIO_I(offset) {HBG_DUMP_REG_TYPE_MDIO, offset, 0} 25*51574da8SJijie Shao #define HBG_DUMP_GMAC_I(offset) {HBG_DUMP_REG_TYPE_GMAC, offset, 0} 26*51574da8SJijie Shao #define HBG_DUMP_PCU_I(offset) {HBG_DUMP_REG_TYPE_PCU, offset, 0} 27*51574da8SJijie Shao 28*51574da8SJijie Shao static const struct hbg_reg_info hbg_dump_reg_infos[] = { 29*51574da8SJijie Shao /* dev specs */ 30*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_SPEC_VALID_ADDR), 31*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_EVENT_REQ_ADDR), 32*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_MAC_ID_ADDR), 33*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_PHY_ID_ADDR), 34*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_MAC_ADDR_ADDR), 35*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_MAC_ADDR_HIGH_ADDR), 36*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_UC_MAC_NUM_ADDR), 37*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_MDIO_FREQ_ADDR), 38*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_MAX_MTU_ADDR), 39*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_MIN_MTU_ADDR), 40*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_TX_FIFO_NUM_ADDR), 41*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_RX_FIFO_NUM_ADDR), 42*51574da8SJijie Shao HBG_DUMP_SPEC_I(HBG_REG_VLAN_LAYERS_ADDR), 43*51574da8SJijie Shao 44*51574da8SJijie Shao /* mdio */ 45*51574da8SJijie Shao HBG_DUMP_MDIO_I(HBG_REG_MDIO_COMMAND_ADDR), 46*51574da8SJijie Shao HBG_DUMP_MDIO_I(HBG_REG_MDIO_ADDR_ADDR), 47*51574da8SJijie Shao HBG_DUMP_MDIO_I(HBG_REG_MDIO_WDATA_ADDR), 48*51574da8SJijie Shao HBG_DUMP_MDIO_I(HBG_REG_MDIO_RDATA_ADDR), 49*51574da8SJijie Shao HBG_DUMP_MDIO_I(HBG_REG_MDIO_STA_ADDR), 50*51574da8SJijie Shao 51*51574da8SJijie Shao /* gmac */ 52*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_DUPLEX_TYPE_ADDR), 53*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_FD_FC_TYPE_ADDR), 54*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_FC_TX_TIMER_ADDR), 55*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_FD_FC_ADDR_LOW_ADDR), 56*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_FD_FC_ADDR_HIGH_ADDR), 57*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_MAX_FRAME_SIZE_ADDR), 58*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_PORT_MODE_ADDR), 59*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_PORT_ENABLE_ADDR), 60*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_PAUSE_ENABLE_ADDR), 61*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_AN_NEG_STATE_ADDR), 62*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_TRANSMIT_CTRL_ADDR), 63*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_REC_FILT_CTRL_ADDR), 64*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_LINE_LOOP_BACK_ADDR), 65*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_CF_CRC_STRIP_ADDR), 66*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_MODE_CHANGE_EN_ADDR), 67*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_LOOP_REG_ADDR), 68*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_RECV_CTRL_ADDR), 69*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_VLAN_CODE_ADDR), 70*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_0_ADDR), 71*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_0_ADDR), 72*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_1_ADDR), 73*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_1_ADDR), 74*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_2_ADDR), 75*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_2_ADDR), 76*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_3_ADDR), 77*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_3_ADDR), 78*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_4_ADDR), 79*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_4_ADDR), 80*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_5_ADDR), 81*51574da8SJijie Shao HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_5_ADDR), 82*51574da8SJijie Shao 83*51574da8SJijie Shao /* pcu */ 84*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_TX_FIFO_THRSLD_ADDR), 85*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_RX_FIFO_THRSLD_ADDR), 86*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CFG_FIFO_THRSLD_ADDR), 87*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_MSK_ADDR), 88*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_STAT_ADDR), 89*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_CLR_ADDR), 90*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_TX_BUS_ERR_ADDR_ADDR), 91*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_RX_BUS_ERR_ADDR_ADDR), 92*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_MAX_FRAME_LEN_ADDR), 93*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_DEBUG_ST_MCH_ADDR), 94*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_FIFO_CURR_STATUS_ADDR), 95*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_FIFO_HIST_STATUS_ADDR), 96*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_CFF_DATA_NUM_ADDR), 97*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_TX_PAUSE_ADDR), 98*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_RX_CFF_ADDR_ADDR), 99*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_RX_BUF_SIZE_ADDR), 100*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_BUS_CTRL_ADDR), 101*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_RX_CTRL_ADDR), 102*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_RX_PKT_MODE_ADDR), 103*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_DBG_ST0_ADDR), 104*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_DBG_ST1_ADDR), 105*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_DBG_ST2_ADDR), 106*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_BUS_RST_EN_ADDR), 107*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_MSK_ADDR), 108*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_STAT_ADDR), 109*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_CLR_ADDR), 110*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_MSK_ADDR), 111*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_STAT_ADDR), 112*51574da8SJijie Shao HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_CLR_ADDR), 113*51574da8SJijie Shao }; 114*51574da8SJijie Shao 115*51574da8SJijie Shao static const u32 hbg_dump_type_base_array[] = { 116*51574da8SJijie Shao [HBG_DUMP_REG_TYPE_SPEC] = 0, 117*51574da8SJijie Shao [HBG_DUMP_REG_TYPE_MDIO] = HBG_REG_MDIO_BASE, 118*51574da8SJijie Shao [HBG_DUMP_REG_TYPE_GMAC] = HBG_REG_SGMII_BASE, 119*51574da8SJijie Shao [HBG_DUMP_REG_TYPE_PCU] = HBG_REG_SGMII_BASE, 120*51574da8SJijie Shao }; 121*51574da8SJijie Shao 122*51574da8SJijie Shao static int hbg_ethtool_get_regs_len(struct net_device *netdev) 123*51574da8SJijie Shao { 124*51574da8SJijie Shao return ARRAY_SIZE(hbg_dump_reg_infos) * sizeof(struct hbg_reg_info); 125*51574da8SJijie Shao } 126*51574da8SJijie Shao 127*51574da8SJijie Shao static void hbg_ethtool_get_regs(struct net_device *netdev, 128*51574da8SJijie Shao struct ethtool_regs *regs, void *data) 129*51574da8SJijie Shao { 130*51574da8SJijie Shao struct hbg_priv *priv = netdev_priv(netdev); 131*51574da8SJijie Shao struct hbg_reg_info *info; 132*51574da8SJijie Shao u32 i, offset = 0; 133*51574da8SJijie Shao 134*51574da8SJijie Shao regs->version = 0; 135*51574da8SJijie Shao for (i = 0; i < ARRAY_SIZE(hbg_dump_reg_infos); i++) { 136*51574da8SJijie Shao info = data + offset; 137*51574da8SJijie Shao 138*51574da8SJijie Shao *info = hbg_dump_reg_infos[i]; 139*51574da8SJijie Shao info->val = hbg_reg_read(priv, info->offset); 140*51574da8SJijie Shao info->offset -= hbg_dump_type_base_array[info->type]; 141*51574da8SJijie Shao 142*51574da8SJijie Shao offset += sizeof(*info); 143*51574da8SJijie Shao } 144*51574da8SJijie Shao } 145e8d13548SJijie Shao 146e8d13548SJijie Shao static const struct ethtool_ops hbg_ethtool_ops = { 147e8d13548SJijie Shao .get_link = ethtool_op_get_link, 148e8d13548SJijie Shao .get_link_ksettings = phy_ethtool_get_link_ksettings, 149e8d13548SJijie Shao .set_link_ksettings = phy_ethtool_set_link_ksettings, 150*51574da8SJijie Shao .get_regs_len = hbg_ethtool_get_regs_len, 151*51574da8SJijie Shao .get_regs = hbg_ethtool_get_regs, 152e8d13548SJijie Shao }; 153e8d13548SJijie Shao 154e8d13548SJijie Shao void hbg_ethtool_set_ops(struct net_device *netdev) 155e8d13548SJijie Shao { 156e8d13548SJijie Shao netdev->ethtool_ops = &hbg_ethtool_ops; 157e8d13548SJijie Shao } 158