193a76530SGrygorii Strashko // SPDX-License-Identifier: GPL-2.0 293a76530SGrygorii Strashko /* Texas Instruments K3 AM65 Ethernet Switch SubSystem Driver ethtool ops 393a76530SGrygorii Strashko * 493a76530SGrygorii Strashko * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ 593a76530SGrygorii Strashko * 693a76530SGrygorii Strashko */ 793a76530SGrygorii Strashko 893a76530SGrygorii Strashko #include <linux/net_tstamp.h> 993a76530SGrygorii Strashko #include <linux/phy.h> 1093a76530SGrygorii Strashko #include <linux/platform_device.h> 1193a76530SGrygorii Strashko #include <linux/pm_runtime.h> 1293a76530SGrygorii Strashko 1393a76530SGrygorii Strashko #include "am65-cpsw-nuss.h" 1493a76530SGrygorii Strashko #include "cpsw_ale.h" 1593a76530SGrygorii Strashko 1693a76530SGrygorii Strashko #define AM65_CPSW_REGDUMP_VER 0x1 1793a76530SGrygorii Strashko 1893a76530SGrygorii Strashko enum { 1993a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_NUSS = 1, 2093a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_RGMII_STATUS = 2, 2193a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_MDIO = 3, 2293a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_CPSW = 4, 2393a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_CPSW_P0 = 5, 2493a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_CPSW_P1 = 6, 2593a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_CPSW_CPTS = 7, 2693a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_CPSW_ALE = 8, 2793a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_CPSW_ALE_TBL = 9, 2893a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_LAST, 2993a76530SGrygorii Strashko }; 3093a76530SGrygorii Strashko 3193a76530SGrygorii Strashko /** 3293a76530SGrygorii Strashko * struct am65_cpsw_regdump_hdr - regdump record header 3393a76530SGrygorii Strashko * 3493a76530SGrygorii Strashko * @module_id: CPSW module ID 3593a76530SGrygorii Strashko * @len: CPSW module registers space length in u32 3693a76530SGrygorii Strashko */ 3793a76530SGrygorii Strashko 3893a76530SGrygorii Strashko struct am65_cpsw_regdump_hdr { 3993a76530SGrygorii Strashko u32 module_id; 4093a76530SGrygorii Strashko u32 len; 4193a76530SGrygorii Strashko }; 4293a76530SGrygorii Strashko 4393a76530SGrygorii Strashko /** 4493a76530SGrygorii Strashko * struct am65_cpsw_regdump_item - regdump module description 4593a76530SGrygorii Strashko * 4693a76530SGrygorii Strashko * @hdr: CPSW module header 4793a76530SGrygorii Strashko * @start_ofs: CPSW module registers start addr 4893a76530SGrygorii Strashko * @end_ofs: CPSW module registers end addr 4993a76530SGrygorii Strashko * 5093a76530SGrygorii Strashko * Registers dump provided in the format: 5193a76530SGrygorii Strashko * u32 : module ID 5293a76530SGrygorii Strashko * u32 : dump length 5393a76530SGrygorii Strashko * u32[..len]: registers values 5493a76530SGrygorii Strashko */ 5593a76530SGrygorii Strashko struct am65_cpsw_regdump_item { 5693a76530SGrygorii Strashko struct am65_cpsw_regdump_hdr hdr; 5793a76530SGrygorii Strashko u32 start_ofs; 5893a76530SGrygorii Strashko u32 end_ofs; 5993a76530SGrygorii Strashko }; 6093a76530SGrygorii Strashko 6193a76530SGrygorii Strashko #define AM65_CPSW_REGDUMP_REC(mod, start, end) { \ 6293a76530SGrygorii Strashko .hdr.module_id = (mod), \ 6393a76530SGrygorii Strashko .hdr.len = (((u32 *)(end)) - ((u32 *)(start)) + 1) * sizeof(u32) * 2 + \ 6493a76530SGrygorii Strashko sizeof(struct am65_cpsw_regdump_hdr), \ 6593a76530SGrygorii Strashko .start_ofs = (start), \ 6693a76530SGrygorii Strashko .end_ofs = end, \ 6793a76530SGrygorii Strashko } 6893a76530SGrygorii Strashko 6993a76530SGrygorii Strashko static const struct am65_cpsw_regdump_item am65_cpsw_regdump[] = { 7093a76530SGrygorii Strashko AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_NUSS, 0x0, 0x1c), 7193a76530SGrygorii Strashko AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_RGMII_STATUS, 0x30, 0x4c), 7293a76530SGrygorii Strashko AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_MDIO, 0xf00, 0xffc), 7393a76530SGrygorii Strashko AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW, 0x20000, 0x2011c), 7493a76530SGrygorii Strashko AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW_P0, 0x21000, 0x21320), 7593a76530SGrygorii Strashko AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW_P1, 0x22000, 0x223a4), 7693a76530SGrygorii Strashko AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW_CPTS, 7793a76530SGrygorii Strashko 0x3d000, 0x3d048), 7893a76530SGrygorii Strashko AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW_ALE, 0x3e000, 0x3e13c), 7993a76530SGrygorii Strashko AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW_ALE_TBL, 0, 0), 8093a76530SGrygorii Strashko }; 8193a76530SGrygorii Strashko 8293a76530SGrygorii Strashko struct am65_cpsw_stats_regs { 8393a76530SGrygorii Strashko u32 rx_good_frames; 8493a76530SGrygorii Strashko u32 rx_broadcast_frames; 8593a76530SGrygorii Strashko u32 rx_multicast_frames; 8693a76530SGrygorii Strashko u32 rx_pause_frames; /* slave */ 8793a76530SGrygorii Strashko u32 rx_crc_errors; 8893a76530SGrygorii Strashko u32 rx_align_code_errors; /* slave */ 8993a76530SGrygorii Strashko u32 rx_oversized_frames; 9093a76530SGrygorii Strashko u32 rx_jabber_frames; /* slave */ 9193a76530SGrygorii Strashko u32 rx_undersized_frames; 9293a76530SGrygorii Strashko u32 rx_fragments; /* slave */ 9393a76530SGrygorii Strashko u32 ale_drop; 9493a76530SGrygorii Strashko u32 ale_overrun_drop; 9593a76530SGrygorii Strashko u32 rx_octets; 9693a76530SGrygorii Strashko u32 tx_good_frames; 9793a76530SGrygorii Strashko u32 tx_broadcast_frames; 9893a76530SGrygorii Strashko u32 tx_multicast_frames; 9993a76530SGrygorii Strashko u32 tx_pause_frames; /* slave */ 10093a76530SGrygorii Strashko u32 tx_deferred_frames; /* slave */ 10193a76530SGrygorii Strashko u32 tx_collision_frames; /* slave */ 10293a76530SGrygorii Strashko u32 tx_single_coll_frames; /* slave */ 10393a76530SGrygorii Strashko u32 tx_mult_coll_frames; /* slave */ 10493a76530SGrygorii Strashko u32 tx_excessive_collisions; /* slave */ 10593a76530SGrygorii Strashko u32 tx_late_collisions; /* slave */ 10693a76530SGrygorii Strashko u32 rx_ipg_error; /* slave 10G only */ 10793a76530SGrygorii Strashko u32 tx_carrier_sense_errors; /* slave */ 10893a76530SGrygorii Strashko u32 tx_octets; 10993a76530SGrygorii Strashko u32 tx_64B_frames; 11093a76530SGrygorii Strashko u32 tx_65_to_127B_frames; 11193a76530SGrygorii Strashko u32 tx_128_to_255B_frames; 11293a76530SGrygorii Strashko u32 tx_256_to_511B_frames; 11393a76530SGrygorii Strashko u32 tx_512_to_1023B_frames; 11493a76530SGrygorii Strashko u32 tx_1024B_frames; 11593a76530SGrygorii Strashko u32 net_octets; 11693a76530SGrygorii Strashko u32 rx_bottom_fifo_drop; 11793a76530SGrygorii Strashko u32 rx_port_mask_drop; 11893a76530SGrygorii Strashko u32 rx_top_fifo_drop; 11993a76530SGrygorii Strashko u32 ale_rate_limit_drop; 12093a76530SGrygorii Strashko u32 ale_vid_ingress_drop; 12193a76530SGrygorii Strashko u32 ale_da_eq_sa_drop; 12293a76530SGrygorii Strashko u32 ale_block_drop; /* K3 */ 12393a76530SGrygorii Strashko u32 ale_secure_drop; /* K3 */ 12493a76530SGrygorii Strashko u32 ale_auth_drop; /* K3 */ 12593a76530SGrygorii Strashko u32 ale_unknown_ucast; 12693a76530SGrygorii Strashko u32 ale_unknown_ucast_bytes; 12793a76530SGrygorii Strashko u32 ale_unknown_mcast; 12893a76530SGrygorii Strashko u32 ale_unknown_mcast_bytes; 12993a76530SGrygorii Strashko u32 ale_unknown_bcast; 13093a76530SGrygorii Strashko u32 ale_unknown_bcast_bytes; 13193a76530SGrygorii Strashko u32 ale_pol_match; 13293a76530SGrygorii Strashko u32 ale_pol_match_red; 13393a76530SGrygorii Strashko u32 ale_pol_match_yellow; 13493a76530SGrygorii Strashko u32 ale_mcast_sa_drop; /* K3 */ 13593a76530SGrygorii Strashko u32 ale_dual_vlan_drop; /* K3 */ 13693a76530SGrygorii Strashko u32 ale_len_err_drop; /* K3 */ 13793a76530SGrygorii Strashko u32 ale_ip_next_hdr_drop; /* K3 */ 13893a76530SGrygorii Strashko u32 ale_ipv4_frag_drop; /* K3 */ 13993a76530SGrygorii Strashko u32 __rsvd_1[24]; 14093a76530SGrygorii Strashko u32 iet_rx_assembly_err; /* K3 slave */ 14193a76530SGrygorii Strashko u32 iet_rx_assembly_ok; /* K3 slave */ 14293a76530SGrygorii Strashko u32 iet_rx_smd_err; /* K3 slave */ 14393a76530SGrygorii Strashko u32 iet_rx_frag; /* K3 slave */ 14493a76530SGrygorii Strashko u32 iet_tx_hold; /* K3 slave */ 14593a76530SGrygorii Strashko u32 iet_tx_frag; /* K3 slave */ 14693a76530SGrygorii Strashko u32 __rsvd_2[9]; 14793a76530SGrygorii Strashko u32 tx_mem_protect_err; 14893a76530SGrygorii Strashko /* following NU only */ 14993a76530SGrygorii Strashko u32 tx_pri0; 15093a76530SGrygorii Strashko u32 tx_pri1; 15193a76530SGrygorii Strashko u32 tx_pri2; 15293a76530SGrygorii Strashko u32 tx_pri3; 15393a76530SGrygorii Strashko u32 tx_pri4; 15493a76530SGrygorii Strashko u32 tx_pri5; 15593a76530SGrygorii Strashko u32 tx_pri6; 15693a76530SGrygorii Strashko u32 tx_pri7; 15793a76530SGrygorii Strashko u32 tx_pri0_bcnt; 15893a76530SGrygorii Strashko u32 tx_pri1_bcnt; 15993a76530SGrygorii Strashko u32 tx_pri2_bcnt; 16093a76530SGrygorii Strashko u32 tx_pri3_bcnt; 16193a76530SGrygorii Strashko u32 tx_pri4_bcnt; 16293a76530SGrygorii Strashko u32 tx_pri5_bcnt; 16393a76530SGrygorii Strashko u32 tx_pri6_bcnt; 16493a76530SGrygorii Strashko u32 tx_pri7_bcnt; 16593a76530SGrygorii Strashko u32 tx_pri0_drop; 16693a76530SGrygorii Strashko u32 tx_pri1_drop; 16793a76530SGrygorii Strashko u32 tx_pri2_drop; 16893a76530SGrygorii Strashko u32 tx_pri3_drop; 16993a76530SGrygorii Strashko u32 tx_pri4_drop; 17093a76530SGrygorii Strashko u32 tx_pri5_drop; 17193a76530SGrygorii Strashko u32 tx_pri6_drop; 17293a76530SGrygorii Strashko u32 tx_pri7_drop; 17393a76530SGrygorii Strashko u32 tx_pri0_drop_bcnt; 17493a76530SGrygorii Strashko u32 tx_pri1_drop_bcnt; 17593a76530SGrygorii Strashko u32 tx_pri2_drop_bcnt; 17693a76530SGrygorii Strashko u32 tx_pri3_drop_bcnt; 17793a76530SGrygorii Strashko u32 tx_pri4_drop_bcnt; 17893a76530SGrygorii Strashko u32 tx_pri5_drop_bcnt; 17993a76530SGrygorii Strashko u32 tx_pri6_drop_bcnt; 18093a76530SGrygorii Strashko u32 tx_pri7_drop_bcnt; 18193a76530SGrygorii Strashko }; 18293a76530SGrygorii Strashko 18393a76530SGrygorii Strashko struct am65_cpsw_ethtool_stat { 18493a76530SGrygorii Strashko char desc[ETH_GSTRING_LEN]; 18593a76530SGrygorii Strashko int offset; 18693a76530SGrygorii Strashko }; 18793a76530SGrygorii Strashko 18893a76530SGrygorii Strashko #define AM65_CPSW_STATS(prefix, field) \ 18993a76530SGrygorii Strashko { \ 19093a76530SGrygorii Strashko #prefix#field, \ 19193a76530SGrygorii Strashko offsetof(struct am65_cpsw_stats_regs, field) \ 19293a76530SGrygorii Strashko } 19393a76530SGrygorii Strashko 19493a76530SGrygorii Strashko static const struct am65_cpsw_ethtool_stat am65_host_stats[] = { 19593a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, rx_good_frames), 19693a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, rx_broadcast_frames), 19793a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, rx_multicast_frames), 19893a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, rx_crc_errors), 19993a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, rx_oversized_frames), 20093a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, rx_undersized_frames), 20193a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_drop), 20293a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_overrun_drop), 20393a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, rx_octets), 20493a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_good_frames), 20593a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_broadcast_frames), 20693a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_multicast_frames), 20793a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_octets), 20893a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_64B_frames), 20993a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_65_to_127B_frames), 21093a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_128_to_255B_frames), 21193a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_256_to_511B_frames), 21293a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_512_to_1023B_frames), 21393a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_1024B_frames), 21493a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, net_octets), 21593a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, rx_bottom_fifo_drop), 21693a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, rx_port_mask_drop), 21793a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, rx_top_fifo_drop), 21893a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_rate_limit_drop), 21993a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_vid_ingress_drop), 22093a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_da_eq_sa_drop), 22193a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_block_drop), 22293a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_secure_drop), 22393a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_auth_drop), 22493a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_unknown_ucast), 22593a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_unknown_ucast_bytes), 22693a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_unknown_mcast), 22793a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_unknown_mcast_bytes), 22893a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_unknown_bcast), 22993a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_unknown_bcast_bytes), 23093a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_pol_match), 23193a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_pol_match_red), 23293a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_pol_match_yellow), 23393a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_mcast_sa_drop), 23493a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_dual_vlan_drop), 23593a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_len_err_drop), 23693a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_ip_next_hdr_drop), 23793a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, ale_ipv4_frag_drop), 23893a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_mem_protect_err), 23993a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri0), 24093a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri1), 24193a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri2), 24293a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri3), 24393a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri4), 24493a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri5), 24593a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri6), 24693a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri7), 24793a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri0_bcnt), 24893a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri1_bcnt), 24993a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri2_bcnt), 25093a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri3_bcnt), 25193a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri4_bcnt), 25293a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri5_bcnt), 25393a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri6_bcnt), 25493a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri7_bcnt), 25593a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri0_drop), 25693a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri1_drop), 25793a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri2_drop), 25893a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri3_drop), 25993a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri4_drop), 26093a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri5_drop), 26193a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri6_drop), 26293a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri7_drop), 26393a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri0_drop_bcnt), 26493a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri1_drop_bcnt), 26593a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri2_drop_bcnt), 26693a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri3_drop_bcnt), 26793a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri4_drop_bcnt), 26893a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri5_drop_bcnt), 26993a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri6_drop_bcnt), 27093a76530SGrygorii Strashko AM65_CPSW_STATS(p0_, tx_pri7_drop_bcnt), 27193a76530SGrygorii Strashko }; 27293a76530SGrygorii Strashko 27393a76530SGrygorii Strashko static const struct am65_cpsw_ethtool_stat am65_slave_stats[] = { 27493a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_good_frames), 27593a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_broadcast_frames), 27693a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_multicast_frames), 27793a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_pause_frames), 27893a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_crc_errors), 27993a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_align_code_errors), 28093a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_oversized_frames), 28193a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_jabber_frames), 28293a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_undersized_frames), 28393a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_fragments), 28493a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_drop), 28593a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_overrun_drop), 28693a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_octets), 28793a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_good_frames), 28893a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_broadcast_frames), 28993a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_multicast_frames), 29093a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pause_frames), 29193a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_deferred_frames), 29293a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_collision_frames), 29393a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_single_coll_frames), 29493a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_mult_coll_frames), 29593a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_excessive_collisions), 29693a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_late_collisions), 29793a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_ipg_error), 29893a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_carrier_sense_errors), 29993a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_octets), 30093a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_64B_frames), 30193a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_65_to_127B_frames), 30293a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_128_to_255B_frames), 30393a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_256_to_511B_frames), 30493a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_512_to_1023B_frames), 30593a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_1024B_frames), 30693a76530SGrygorii Strashko AM65_CPSW_STATS(, net_octets), 30793a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_bottom_fifo_drop), 30893a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_port_mask_drop), 30993a76530SGrygorii Strashko AM65_CPSW_STATS(, rx_top_fifo_drop), 31093a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_rate_limit_drop), 31193a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_vid_ingress_drop), 31293a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_da_eq_sa_drop), 31393a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_block_drop), 31493a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_secure_drop), 31593a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_auth_drop), 31693a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_unknown_ucast), 31793a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_unknown_ucast_bytes), 31893a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_unknown_mcast), 31993a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_unknown_mcast_bytes), 32093a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_unknown_bcast), 32193a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_unknown_bcast_bytes), 32293a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_pol_match), 32393a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_pol_match_red), 32493a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_pol_match_yellow), 32593a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_mcast_sa_drop), 32693a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_dual_vlan_drop), 32793a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_len_err_drop), 32893a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_ip_next_hdr_drop), 32993a76530SGrygorii Strashko AM65_CPSW_STATS(, ale_ipv4_frag_drop), 33093a76530SGrygorii Strashko AM65_CPSW_STATS(, iet_rx_assembly_err), 33193a76530SGrygorii Strashko AM65_CPSW_STATS(, iet_rx_assembly_ok), 33293a76530SGrygorii Strashko AM65_CPSW_STATS(, iet_rx_smd_err), 33393a76530SGrygorii Strashko AM65_CPSW_STATS(, iet_rx_frag), 33493a76530SGrygorii Strashko AM65_CPSW_STATS(, iet_tx_hold), 33593a76530SGrygorii Strashko AM65_CPSW_STATS(, iet_tx_frag), 33693a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_mem_protect_err), 33793a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri0), 33893a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri1), 33993a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri2), 34093a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri3), 34193a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri4), 34293a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri5), 34393a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri6), 34493a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri7), 34593a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri0_bcnt), 34693a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri1_bcnt), 34793a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri2_bcnt), 34893a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri3_bcnt), 34993a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri4_bcnt), 35093a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri5_bcnt), 35193a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri6_bcnt), 35293a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri7_bcnt), 35393a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri0_drop), 35493a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri1_drop), 35593a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri2_drop), 35693a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri3_drop), 35793a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri4_drop), 35893a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri5_drop), 35993a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri6_drop), 36093a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri7_drop), 36193a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri0_drop_bcnt), 36293a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri1_drop_bcnt), 36393a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri2_drop_bcnt), 36493a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri3_drop_bcnt), 36593a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri4_drop_bcnt), 36693a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri5_drop_bcnt), 36793a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri6_drop_bcnt), 36893a76530SGrygorii Strashko AM65_CPSW_STATS(, tx_pri7_drop_bcnt), 36993a76530SGrygorii Strashko }; 37093a76530SGrygorii Strashko 37193a76530SGrygorii Strashko /* Ethtool priv_flags */ 37293a76530SGrygorii Strashko static const char am65_cpsw_ethtool_priv_flags[][ETH_GSTRING_LEN] = { 37393a76530SGrygorii Strashko #define AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN BIT(0) 37493a76530SGrygorii Strashko "p0-rx-ptype-rrobin", 37593a76530SGrygorii Strashko }; 37693a76530SGrygorii Strashko 37793a76530SGrygorii Strashko static int am65_cpsw_ethtool_op_begin(struct net_device *ndev) 37893a76530SGrygorii Strashko { 37993a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 38093a76530SGrygorii Strashko int ret; 38193a76530SGrygorii Strashko 38293a76530SGrygorii Strashko ret = pm_runtime_get_sync(common->dev); 38393a76530SGrygorii Strashko if (ret < 0) { 38493a76530SGrygorii Strashko dev_err(common->dev, "ethtool begin failed %d\n", ret); 38593a76530SGrygorii Strashko pm_runtime_put_noidle(common->dev); 38693a76530SGrygorii Strashko } 38793a76530SGrygorii Strashko 38893a76530SGrygorii Strashko return ret; 38993a76530SGrygorii Strashko } 39093a76530SGrygorii Strashko 39193a76530SGrygorii Strashko static void am65_cpsw_ethtool_op_complete(struct net_device *ndev) 39293a76530SGrygorii Strashko { 39393a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 39493a76530SGrygorii Strashko int ret; 39593a76530SGrygorii Strashko 39693a76530SGrygorii Strashko ret = pm_runtime_put(common->dev); 39793a76530SGrygorii Strashko if (ret < 0 && ret != -EBUSY) 39893a76530SGrygorii Strashko dev_err(common->dev, "ethtool complete failed %d\n", ret); 39993a76530SGrygorii Strashko } 40093a76530SGrygorii Strashko 40193a76530SGrygorii Strashko static void am65_cpsw_get_drvinfo(struct net_device *ndev, 40293a76530SGrygorii Strashko struct ethtool_drvinfo *info) 40393a76530SGrygorii Strashko { 40493a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 40593a76530SGrygorii Strashko 40693a76530SGrygorii Strashko strlcpy(info->driver, dev_driver_string(common->dev), 40793a76530SGrygorii Strashko sizeof(info->driver)); 40893a76530SGrygorii Strashko strlcpy(info->bus_info, dev_name(common->dev), sizeof(info->bus_info)); 40993a76530SGrygorii Strashko } 41093a76530SGrygorii Strashko 41193a76530SGrygorii Strashko static u32 am65_cpsw_get_msglevel(struct net_device *ndev) 41293a76530SGrygorii Strashko { 41393a76530SGrygorii Strashko struct am65_cpsw_ndev_priv *priv = am65_ndev_to_priv(ndev); 41493a76530SGrygorii Strashko 41593a76530SGrygorii Strashko return priv->msg_enable; 41693a76530SGrygorii Strashko } 41793a76530SGrygorii Strashko 41893a76530SGrygorii Strashko static void am65_cpsw_set_msglevel(struct net_device *ndev, u32 value) 41993a76530SGrygorii Strashko { 42093a76530SGrygorii Strashko struct am65_cpsw_ndev_priv *priv = am65_ndev_to_priv(ndev); 42193a76530SGrygorii Strashko 42293a76530SGrygorii Strashko priv->msg_enable = value; 42393a76530SGrygorii Strashko } 42493a76530SGrygorii Strashko 42593a76530SGrygorii Strashko static void am65_cpsw_get_channels(struct net_device *ndev, 42693a76530SGrygorii Strashko struct ethtool_channels *ch) 42793a76530SGrygorii Strashko { 42893a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 42993a76530SGrygorii Strashko 43093a76530SGrygorii Strashko ch->max_rx = AM65_CPSW_MAX_RX_QUEUES; 43193a76530SGrygorii Strashko ch->max_tx = AM65_CPSW_MAX_TX_QUEUES; 43293a76530SGrygorii Strashko ch->rx_count = AM65_CPSW_MAX_RX_QUEUES; 43393a76530SGrygorii Strashko ch->tx_count = common->tx_ch_num; 43493a76530SGrygorii Strashko } 43593a76530SGrygorii Strashko 43693a76530SGrygorii Strashko static int am65_cpsw_set_channels(struct net_device *ndev, 43793a76530SGrygorii Strashko struct ethtool_channels *chs) 43893a76530SGrygorii Strashko { 43993a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 44093a76530SGrygorii Strashko 44193a76530SGrygorii Strashko if (!chs->rx_count || !chs->tx_count) 44293a76530SGrygorii Strashko return -EINVAL; 44393a76530SGrygorii Strashko 44493a76530SGrygorii Strashko /* Check if interface is up. Can change the num queues when 44593a76530SGrygorii Strashko * the interface is down. 44693a76530SGrygorii Strashko */ 44793a76530SGrygorii Strashko if (netif_running(ndev)) 44893a76530SGrygorii Strashko return -EBUSY; 44993a76530SGrygorii Strashko 45093a76530SGrygorii Strashko am65_cpsw_nuss_remove_tx_chns(common); 45193a76530SGrygorii Strashko 45293a76530SGrygorii Strashko return am65_cpsw_nuss_update_tx_chns(common, chs->tx_count); 45393a76530SGrygorii Strashko } 45493a76530SGrygorii Strashko 45593a76530SGrygorii Strashko static void am65_cpsw_get_ringparam(struct net_device *ndev, 45693a76530SGrygorii Strashko struct ethtool_ringparam *ering) 45793a76530SGrygorii Strashko { 45893a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 45993a76530SGrygorii Strashko 46093a76530SGrygorii Strashko /* not supported */ 46193a76530SGrygorii Strashko ering->tx_pending = common->tx_chns[0].descs_num; 46293a76530SGrygorii Strashko ering->rx_pending = common->rx_chns.descs_num; 46393a76530SGrygorii Strashko } 46493a76530SGrygorii Strashko 46593a76530SGrygorii Strashko static void am65_cpsw_get_pauseparam(struct net_device *ndev, 46693a76530SGrygorii Strashko struct ethtool_pauseparam *pause) 46793a76530SGrygorii Strashko { 46893a76530SGrygorii Strashko struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev); 46993a76530SGrygorii Strashko 47093a76530SGrygorii Strashko pause->autoneg = AUTONEG_DISABLE; 47193a76530SGrygorii Strashko pause->rx_pause = salve->rx_pause ? true : false; 47293a76530SGrygorii Strashko pause->tx_pause = salve->tx_pause ? true : false; 47393a76530SGrygorii Strashko } 47493a76530SGrygorii Strashko 47593a76530SGrygorii Strashko static int am65_cpsw_set_pauseparam(struct net_device *ndev, 47693a76530SGrygorii Strashko struct ethtool_pauseparam *pause) 47793a76530SGrygorii Strashko { 47893a76530SGrygorii Strashko struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev); 47993a76530SGrygorii Strashko 48093a76530SGrygorii Strashko if (!salve->phy) 48193a76530SGrygorii Strashko return -EINVAL; 48293a76530SGrygorii Strashko 48393a76530SGrygorii Strashko if (!phy_validate_pause(salve->phy, pause)) 48493a76530SGrygorii Strashko return -EINVAL; 48593a76530SGrygorii Strashko 48693a76530SGrygorii Strashko salve->rx_pause = pause->rx_pause ? true : false; 48793a76530SGrygorii Strashko salve->tx_pause = pause->tx_pause ? true : false; 48893a76530SGrygorii Strashko 48993a76530SGrygorii Strashko phy_set_asym_pause(salve->phy, salve->rx_pause, salve->tx_pause); 49093a76530SGrygorii Strashko 49193a76530SGrygorii Strashko return 0; 49293a76530SGrygorii Strashko } 49393a76530SGrygorii Strashko 49493a76530SGrygorii Strashko static void am65_cpsw_get_wol(struct net_device *ndev, 49593a76530SGrygorii Strashko struct ethtool_wolinfo *wol) 49693a76530SGrygorii Strashko { 49793a76530SGrygorii Strashko struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev); 49893a76530SGrygorii Strashko 49993a76530SGrygorii Strashko wol->supported = 0; 50093a76530SGrygorii Strashko wol->wolopts = 0; 50193a76530SGrygorii Strashko 50293a76530SGrygorii Strashko if (salve->phy) 50393a76530SGrygorii Strashko phy_ethtool_get_wol(salve->phy, wol); 50493a76530SGrygorii Strashko } 50593a76530SGrygorii Strashko 50693a76530SGrygorii Strashko static int am65_cpsw_set_wol(struct net_device *ndev, 50793a76530SGrygorii Strashko struct ethtool_wolinfo *wol) 50893a76530SGrygorii Strashko { 50993a76530SGrygorii Strashko struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev); 51093a76530SGrygorii Strashko 51193a76530SGrygorii Strashko if (!salve->phy) 51293a76530SGrygorii Strashko return -EOPNOTSUPP; 51393a76530SGrygorii Strashko 51493a76530SGrygorii Strashko return phy_ethtool_set_wol(salve->phy, wol); 51593a76530SGrygorii Strashko } 51693a76530SGrygorii Strashko 51793a76530SGrygorii Strashko static int am65_cpsw_get_link_ksettings(struct net_device *ndev, 51893a76530SGrygorii Strashko struct ethtool_link_ksettings *ecmd) 51993a76530SGrygorii Strashko { 52093a76530SGrygorii Strashko struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev); 52193a76530SGrygorii Strashko 52293a76530SGrygorii Strashko if (!salve->phy) 52393a76530SGrygorii Strashko return -EOPNOTSUPP; 52493a76530SGrygorii Strashko 52593a76530SGrygorii Strashko phy_ethtool_ksettings_get(salve->phy, ecmd); 52693a76530SGrygorii Strashko return 0; 52793a76530SGrygorii Strashko } 52893a76530SGrygorii Strashko 52993a76530SGrygorii Strashko static int 53093a76530SGrygorii Strashko am65_cpsw_set_link_ksettings(struct net_device *ndev, 53193a76530SGrygorii Strashko const struct ethtool_link_ksettings *ecmd) 53293a76530SGrygorii Strashko { 53393a76530SGrygorii Strashko struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev); 53493a76530SGrygorii Strashko 53593a76530SGrygorii Strashko if (!salve->phy || phy_is_pseudo_fixed_link(salve->phy)) 53693a76530SGrygorii Strashko return -EOPNOTSUPP; 53793a76530SGrygorii Strashko 53893a76530SGrygorii Strashko return phy_ethtool_ksettings_set(salve->phy, ecmd); 53993a76530SGrygorii Strashko } 54093a76530SGrygorii Strashko 54193a76530SGrygorii Strashko static int am65_cpsw_get_eee(struct net_device *ndev, struct ethtool_eee *edata) 54293a76530SGrygorii Strashko { 54393a76530SGrygorii Strashko struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev); 54493a76530SGrygorii Strashko 54593a76530SGrygorii Strashko if (!salve->phy || phy_is_pseudo_fixed_link(salve->phy)) 54693a76530SGrygorii Strashko return -EOPNOTSUPP; 54793a76530SGrygorii Strashko 54893a76530SGrygorii Strashko return phy_ethtool_get_eee(salve->phy, edata); 54993a76530SGrygorii Strashko } 55093a76530SGrygorii Strashko 55193a76530SGrygorii Strashko static int am65_cpsw_set_eee(struct net_device *ndev, struct ethtool_eee *edata) 55293a76530SGrygorii Strashko { 55393a76530SGrygorii Strashko struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev); 55493a76530SGrygorii Strashko 55593a76530SGrygorii Strashko if (!salve->phy || phy_is_pseudo_fixed_link(salve->phy)) 55693a76530SGrygorii Strashko return -EOPNOTSUPP; 55793a76530SGrygorii Strashko 55893a76530SGrygorii Strashko return phy_ethtool_set_eee(salve->phy, edata); 55993a76530SGrygorii Strashko } 56093a76530SGrygorii Strashko 56193a76530SGrygorii Strashko static int am65_cpsw_nway_reset(struct net_device *ndev) 56293a76530SGrygorii Strashko { 56393a76530SGrygorii Strashko struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev); 56493a76530SGrygorii Strashko 56593a76530SGrygorii Strashko if (!salve->phy || phy_is_pseudo_fixed_link(salve->phy)) 56693a76530SGrygorii Strashko return -EOPNOTSUPP; 56793a76530SGrygorii Strashko 56893a76530SGrygorii Strashko return phy_restart_aneg(salve->phy); 56993a76530SGrygorii Strashko } 57093a76530SGrygorii Strashko 57193a76530SGrygorii Strashko static int am65_cpsw_get_regs_len(struct net_device *ndev) 57293a76530SGrygorii Strashko { 57393a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 57493a76530SGrygorii Strashko u32 i, regdump_len = 0; 57593a76530SGrygorii Strashko 57693a76530SGrygorii Strashko for (i = 0; i < ARRAY_SIZE(am65_cpsw_regdump); i++) { 57793a76530SGrygorii Strashko if (am65_cpsw_regdump[i].hdr.module_id == 57893a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_CPSW_ALE_TBL) { 57993a76530SGrygorii Strashko regdump_len += sizeof(struct am65_cpsw_regdump_hdr); 58093a76530SGrygorii Strashko regdump_len += common->ale->params.ale_entries * 58193a76530SGrygorii Strashko ALE_ENTRY_WORDS * sizeof(u32); 58293a76530SGrygorii Strashko continue; 58393a76530SGrygorii Strashko } 58493a76530SGrygorii Strashko regdump_len += am65_cpsw_regdump[i].hdr.len; 58593a76530SGrygorii Strashko } 58693a76530SGrygorii Strashko 58793a76530SGrygorii Strashko return regdump_len; 58893a76530SGrygorii Strashko } 58993a76530SGrygorii Strashko 59093a76530SGrygorii Strashko static void am65_cpsw_get_regs(struct net_device *ndev, 59193a76530SGrygorii Strashko struct ethtool_regs *regs, void *p) 59293a76530SGrygorii Strashko { 59393a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 59493a76530SGrygorii Strashko u32 i, j, pos, *reg = p; 59593a76530SGrygorii Strashko 59693a76530SGrygorii Strashko /* update CPSW IP version */ 59793a76530SGrygorii Strashko regs->version = AM65_CPSW_REGDUMP_VER; 59893a76530SGrygorii Strashko 59993a76530SGrygorii Strashko pos = 0; 60093a76530SGrygorii Strashko for (i = 0; i < ARRAY_SIZE(am65_cpsw_regdump); i++) { 60193a76530SGrygorii Strashko reg[pos++] = am65_cpsw_regdump[i].hdr.module_id; 60293a76530SGrygorii Strashko 60393a76530SGrygorii Strashko if (am65_cpsw_regdump[i].hdr.module_id == 60493a76530SGrygorii Strashko AM65_CPSW_REGDUMP_MOD_CPSW_ALE_TBL) { 60593a76530SGrygorii Strashko u32 ale_tbl_len = common->ale->params.ale_entries * 60693a76530SGrygorii Strashko ALE_ENTRY_WORDS * sizeof(u32) + 60793a76530SGrygorii Strashko sizeof(struct am65_cpsw_regdump_hdr); 60893a76530SGrygorii Strashko reg[pos++] = ale_tbl_len; 60993a76530SGrygorii Strashko cpsw_ale_dump(common->ale, ®[pos]); 61093a76530SGrygorii Strashko pos += ale_tbl_len; 61193a76530SGrygorii Strashko continue; 61293a76530SGrygorii Strashko } 61393a76530SGrygorii Strashko 61493a76530SGrygorii Strashko reg[pos++] = am65_cpsw_regdump[i].hdr.len; 61593a76530SGrygorii Strashko 61693a76530SGrygorii Strashko j = am65_cpsw_regdump[i].start_ofs; 61793a76530SGrygorii Strashko do { 61893a76530SGrygorii Strashko reg[pos++] = j; 61993a76530SGrygorii Strashko reg[pos++] = readl_relaxed(common->ss_base + j); 62093a76530SGrygorii Strashko j += sizeof(u32); 62193a76530SGrygorii Strashko } while (j <= am65_cpsw_regdump[i].end_ofs); 62293a76530SGrygorii Strashko } 62393a76530SGrygorii Strashko } 62493a76530SGrygorii Strashko 62593a76530SGrygorii Strashko static int am65_cpsw_get_sset_count(struct net_device *ndev, int sset) 62693a76530SGrygorii Strashko { 62793a76530SGrygorii Strashko switch (sset) { 62893a76530SGrygorii Strashko case ETH_SS_STATS: 62993a76530SGrygorii Strashko return ARRAY_SIZE(am65_host_stats) + 63093a76530SGrygorii Strashko ARRAY_SIZE(am65_slave_stats); 63193a76530SGrygorii Strashko case ETH_SS_PRIV_FLAGS: 63293a76530SGrygorii Strashko return ARRAY_SIZE(am65_cpsw_ethtool_priv_flags); 63393a76530SGrygorii Strashko default: 63493a76530SGrygorii Strashko return -EOPNOTSUPP; 63593a76530SGrygorii Strashko } 63693a76530SGrygorii Strashko } 63793a76530SGrygorii Strashko 63893a76530SGrygorii Strashko static void am65_cpsw_get_strings(struct net_device *ndev, 63993a76530SGrygorii Strashko u32 stringset, u8 *data) 64093a76530SGrygorii Strashko { 64193a76530SGrygorii Strashko const struct am65_cpsw_ethtool_stat *hw_stats; 64293a76530SGrygorii Strashko u32 i, num_stats; 64393a76530SGrygorii Strashko u8 *p = data; 64493a76530SGrygorii Strashko 64593a76530SGrygorii Strashko switch (stringset) { 64693a76530SGrygorii Strashko case ETH_SS_STATS: 64793a76530SGrygorii Strashko num_stats = ARRAY_SIZE(am65_host_stats); 64893a76530SGrygorii Strashko hw_stats = am65_host_stats; 64993a76530SGrygorii Strashko for (i = 0; i < num_stats; i++) { 65093a76530SGrygorii Strashko memcpy(p, hw_stats[i].desc, ETH_GSTRING_LEN); 65193a76530SGrygorii Strashko p += ETH_GSTRING_LEN; 65293a76530SGrygorii Strashko } 65393a76530SGrygorii Strashko 65493a76530SGrygorii Strashko num_stats = ARRAY_SIZE(am65_slave_stats); 65593a76530SGrygorii Strashko hw_stats = am65_slave_stats; 65693a76530SGrygorii Strashko for (i = 0; i < num_stats; i++) { 65793a76530SGrygorii Strashko memcpy(p, hw_stats[i].desc, ETH_GSTRING_LEN); 65893a76530SGrygorii Strashko p += ETH_GSTRING_LEN; 65993a76530SGrygorii Strashko } 66093a76530SGrygorii Strashko break; 66193a76530SGrygorii Strashko case ETH_SS_PRIV_FLAGS: 66293a76530SGrygorii Strashko num_stats = ARRAY_SIZE(am65_cpsw_ethtool_priv_flags); 66393a76530SGrygorii Strashko 66493a76530SGrygorii Strashko for (i = 0; i < num_stats; i++) { 66593a76530SGrygorii Strashko memcpy(p, am65_cpsw_ethtool_priv_flags[i], 66693a76530SGrygorii Strashko ETH_GSTRING_LEN); 66793a76530SGrygorii Strashko p += ETH_GSTRING_LEN; 66893a76530SGrygorii Strashko } 66993a76530SGrygorii Strashko break; 67093a76530SGrygorii Strashko } 67193a76530SGrygorii Strashko } 67293a76530SGrygorii Strashko 67393a76530SGrygorii Strashko static void am65_cpsw_get_ethtool_stats(struct net_device *ndev, 67493a76530SGrygorii Strashko struct ethtool_stats *stats, u64 *data) 67593a76530SGrygorii Strashko { 67693a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 67793a76530SGrygorii Strashko const struct am65_cpsw_ethtool_stat *hw_stats; 67893a76530SGrygorii Strashko struct am65_cpsw_host *host_p; 67993a76530SGrygorii Strashko struct am65_cpsw_port *port; 68093a76530SGrygorii Strashko u32 i, num_stats; 68193a76530SGrygorii Strashko 68293a76530SGrygorii Strashko host_p = am65_common_get_host(common); 68393a76530SGrygorii Strashko port = am65_ndev_to_port(ndev); 68493a76530SGrygorii Strashko num_stats = ARRAY_SIZE(am65_host_stats); 68593a76530SGrygorii Strashko hw_stats = am65_host_stats; 68693a76530SGrygorii Strashko for (i = 0; i < num_stats; i++) 68793a76530SGrygorii Strashko *data++ = readl_relaxed(host_p->stat_base + 68893a76530SGrygorii Strashko hw_stats[i].offset); 68993a76530SGrygorii Strashko 69093a76530SGrygorii Strashko num_stats = ARRAY_SIZE(am65_slave_stats); 69193a76530SGrygorii Strashko hw_stats = am65_slave_stats; 69293a76530SGrygorii Strashko for (i = 0; i < num_stats; i++) 69393a76530SGrygorii Strashko *data++ = readl_relaxed(port->stat_base + 69493a76530SGrygorii Strashko hw_stats[i].offset); 69593a76530SGrygorii Strashko } 69693a76530SGrygorii Strashko 69793a76530SGrygorii Strashko static u32 am65_cpsw_get_ethtool_priv_flags(struct net_device *ndev) 69893a76530SGrygorii Strashko { 69993a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 70093a76530SGrygorii Strashko u32 priv_flags = 0; 70193a76530SGrygorii Strashko 70293a76530SGrygorii Strashko if (common->pf_p0_rx_ptype_rrobin) 70393a76530SGrygorii Strashko priv_flags |= AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN; 70493a76530SGrygorii Strashko 70593a76530SGrygorii Strashko return priv_flags; 70693a76530SGrygorii Strashko } 70793a76530SGrygorii Strashko 70893a76530SGrygorii Strashko static int am65_cpsw_set_ethtool_priv_flags(struct net_device *ndev, u32 flags) 70993a76530SGrygorii Strashko { 71093a76530SGrygorii Strashko struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 71193a76530SGrygorii Strashko 71293a76530SGrygorii Strashko common->pf_p0_rx_ptype_rrobin = 71393a76530SGrygorii Strashko !!(flags & AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN); 71493a76530SGrygorii Strashko am65_cpsw_nuss_set_p0_ptype(common); 71593a76530SGrygorii Strashko 71693a76530SGrygorii Strashko return 0; 71793a76530SGrygorii Strashko } 71893a76530SGrygorii Strashko 71993a76530SGrygorii Strashko const struct ethtool_ops am65_cpsw_ethtool_ops_slave = { 72093a76530SGrygorii Strashko .begin = am65_cpsw_ethtool_op_begin, 72193a76530SGrygorii Strashko .complete = am65_cpsw_ethtool_op_complete, 72293a76530SGrygorii Strashko .get_drvinfo = am65_cpsw_get_drvinfo, 72393a76530SGrygorii Strashko .get_msglevel = am65_cpsw_get_msglevel, 72493a76530SGrygorii Strashko .set_msglevel = am65_cpsw_set_msglevel, 72593a76530SGrygorii Strashko .get_channels = am65_cpsw_get_channels, 72693a76530SGrygorii Strashko .set_channels = am65_cpsw_set_channels, 72793a76530SGrygorii Strashko .get_ringparam = am65_cpsw_get_ringparam, 72893a76530SGrygorii Strashko .get_regs_len = am65_cpsw_get_regs_len, 72993a76530SGrygorii Strashko .get_regs = am65_cpsw_get_regs, 73093a76530SGrygorii Strashko .get_sset_count = am65_cpsw_get_sset_count, 73193a76530SGrygorii Strashko .get_strings = am65_cpsw_get_strings, 73293a76530SGrygorii Strashko .get_ethtool_stats = am65_cpsw_get_ethtool_stats, 73393a76530SGrygorii Strashko .get_ts_info = ethtool_op_get_ts_info, 73493a76530SGrygorii Strashko .get_priv_flags = am65_cpsw_get_ethtool_priv_flags, 73593a76530SGrygorii Strashko .set_priv_flags = am65_cpsw_set_ethtool_priv_flags, 73693a76530SGrygorii Strashko 73793a76530SGrygorii Strashko .get_link = ethtool_op_get_link, 73893a76530SGrygorii Strashko .get_link_ksettings = am65_cpsw_get_link_ksettings, 73993a76530SGrygorii Strashko .set_link_ksettings = am65_cpsw_set_link_ksettings, 74093a76530SGrygorii Strashko .get_pauseparam = am65_cpsw_get_pauseparam, 74193a76530SGrygorii Strashko .set_pauseparam = am65_cpsw_set_pauseparam, 74293a76530SGrygorii Strashko .get_wol = am65_cpsw_get_wol, 74393a76530SGrygorii Strashko .set_wol = am65_cpsw_set_wol, 74493a76530SGrygorii Strashko .get_eee = am65_cpsw_get_eee, 74593a76530SGrygorii Strashko .set_eee = am65_cpsw_set_eee, 74693a76530SGrygorii Strashko .nway_reset = am65_cpsw_nway_reset, 74793a76530SGrygorii Strashko }; 748