18c2ecf20Sopenharmony_ci/********************************************************************** 28c2ecf20Sopenharmony_ci * Author: Cavium, Inc. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Contact: support@cavium.com 58c2ecf20Sopenharmony_ci * Please include "LiquidIO" in the subject. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (c) 2003-2016 Cavium, Inc. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * This file is free software; you can redistribute it and/or modify 108c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License, Version 2, as 118c2ecf20Sopenharmony_ci * published by the Free Software Foundation. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * This file is distributed in the hope that it will be useful, but 148c2ecf20Sopenharmony_ci * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 158c2ecf20Sopenharmony_ci * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 168c2ecf20Sopenharmony_ci * NONINFRINGEMENT. See the GNU General Public License for more details. 178c2ecf20Sopenharmony_ci ***********************************************************************/ 188c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 198c2ecf20Sopenharmony_ci#include <linux/net_tstamp.h> 208c2ecf20Sopenharmony_ci#include <linux/pci.h> 218c2ecf20Sopenharmony_ci#include "liquidio_common.h" 228c2ecf20Sopenharmony_ci#include "octeon_droq.h" 238c2ecf20Sopenharmony_ci#include "octeon_iq.h" 248c2ecf20Sopenharmony_ci#include "response_manager.h" 258c2ecf20Sopenharmony_ci#include "octeon_device.h" 268c2ecf20Sopenharmony_ci#include "octeon_nic.h" 278c2ecf20Sopenharmony_ci#include "octeon_main.h" 288c2ecf20Sopenharmony_ci#include "octeon_network.h" 298c2ecf20Sopenharmony_ci#include "cn66xx_regs.h" 308c2ecf20Sopenharmony_ci#include "cn66xx_device.h" 318c2ecf20Sopenharmony_ci#include "cn23xx_pf_device.h" 328c2ecf20Sopenharmony_ci#include "cn23xx_vf_device.h" 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic int lio_reset_queues(struct net_device *netdev, uint32_t num_qs); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistruct oct_intrmod_resp { 378c2ecf20Sopenharmony_ci u64 rh; 388c2ecf20Sopenharmony_ci struct oct_intrmod_cfg intrmod; 398c2ecf20Sopenharmony_ci u64 status; 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistruct oct_mdio_cmd_resp { 438c2ecf20Sopenharmony_ci u64 rh; 448c2ecf20Sopenharmony_ci struct oct_mdio_cmd resp; 458c2ecf20Sopenharmony_ci u64 status; 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#define OCT_MDIO45_RESP_SIZE (sizeof(struct oct_mdio_cmd_resp)) 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci/* Octeon's interface mode of operation */ 518c2ecf20Sopenharmony_cienum { 528c2ecf20Sopenharmony_ci INTERFACE_MODE_DISABLED, 538c2ecf20Sopenharmony_ci INTERFACE_MODE_RGMII, 548c2ecf20Sopenharmony_ci INTERFACE_MODE_GMII, 558c2ecf20Sopenharmony_ci INTERFACE_MODE_SPI, 568c2ecf20Sopenharmony_ci INTERFACE_MODE_PCIE, 578c2ecf20Sopenharmony_ci INTERFACE_MODE_XAUI, 588c2ecf20Sopenharmony_ci INTERFACE_MODE_SGMII, 598c2ecf20Sopenharmony_ci INTERFACE_MODE_PICMG, 608c2ecf20Sopenharmony_ci INTERFACE_MODE_NPI, 618c2ecf20Sopenharmony_ci INTERFACE_MODE_LOOP, 628c2ecf20Sopenharmony_ci INTERFACE_MODE_SRIO, 638c2ecf20Sopenharmony_ci INTERFACE_MODE_ILK, 648c2ecf20Sopenharmony_ci INTERFACE_MODE_RXAUI, 658c2ecf20Sopenharmony_ci INTERFACE_MODE_QSGMII, 668c2ecf20Sopenharmony_ci INTERFACE_MODE_AGL, 678c2ecf20Sopenharmony_ci INTERFACE_MODE_XLAUI, 688c2ecf20Sopenharmony_ci INTERFACE_MODE_XFI, 698c2ecf20Sopenharmony_ci INTERFACE_MODE_10G_KR, 708c2ecf20Sopenharmony_ci INTERFACE_MODE_40G_KR4, 718c2ecf20Sopenharmony_ci INTERFACE_MODE_MIXED, 728c2ecf20Sopenharmony_ci}; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci#define OCT_ETHTOOL_REGDUMP_LEN 4096 758c2ecf20Sopenharmony_ci#define OCT_ETHTOOL_REGDUMP_LEN_23XX (4096 * 11) 768c2ecf20Sopenharmony_ci#define OCT_ETHTOOL_REGDUMP_LEN_23XX_VF (4096 * 2) 778c2ecf20Sopenharmony_ci#define OCT_ETHTOOL_REGSVER 1 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci/* statistics of PF */ 808c2ecf20Sopenharmony_cistatic const char oct_stats_strings[][ETH_GSTRING_LEN] = { 818c2ecf20Sopenharmony_ci "rx_packets", 828c2ecf20Sopenharmony_ci "tx_packets", 838c2ecf20Sopenharmony_ci "rx_bytes", 848c2ecf20Sopenharmony_ci "tx_bytes", 858c2ecf20Sopenharmony_ci "rx_errors", 868c2ecf20Sopenharmony_ci "tx_errors", 878c2ecf20Sopenharmony_ci "rx_dropped", 888c2ecf20Sopenharmony_ci "tx_dropped", 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci "tx_total_sent", 918c2ecf20Sopenharmony_ci "tx_total_fwd", 928c2ecf20Sopenharmony_ci "tx_err_pko", 938c2ecf20Sopenharmony_ci "tx_err_pki", 948c2ecf20Sopenharmony_ci "tx_err_link", 958c2ecf20Sopenharmony_ci "tx_err_drop", 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci "tx_tso", 988c2ecf20Sopenharmony_ci "tx_tso_packets", 998c2ecf20Sopenharmony_ci "tx_tso_err", 1008c2ecf20Sopenharmony_ci "tx_vxlan", 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci "tx_mcast", 1038c2ecf20Sopenharmony_ci "tx_bcast", 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci "mac_tx_total_pkts", 1068c2ecf20Sopenharmony_ci "mac_tx_total_bytes", 1078c2ecf20Sopenharmony_ci "mac_tx_mcast_pkts", 1088c2ecf20Sopenharmony_ci "mac_tx_bcast_pkts", 1098c2ecf20Sopenharmony_ci "mac_tx_ctl_packets", 1108c2ecf20Sopenharmony_ci "mac_tx_total_collisions", 1118c2ecf20Sopenharmony_ci "mac_tx_one_collision", 1128c2ecf20Sopenharmony_ci "mac_tx_multi_collision", 1138c2ecf20Sopenharmony_ci "mac_tx_max_collision_fail", 1148c2ecf20Sopenharmony_ci "mac_tx_max_deferral_fail", 1158c2ecf20Sopenharmony_ci "mac_tx_fifo_err", 1168c2ecf20Sopenharmony_ci "mac_tx_runts", 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci "rx_total_rcvd", 1198c2ecf20Sopenharmony_ci "rx_total_fwd", 1208c2ecf20Sopenharmony_ci "rx_mcast", 1218c2ecf20Sopenharmony_ci "rx_bcast", 1228c2ecf20Sopenharmony_ci "rx_jabber_err", 1238c2ecf20Sopenharmony_ci "rx_l2_err", 1248c2ecf20Sopenharmony_ci "rx_frame_err", 1258c2ecf20Sopenharmony_ci "rx_err_pko", 1268c2ecf20Sopenharmony_ci "rx_err_link", 1278c2ecf20Sopenharmony_ci "rx_err_drop", 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci "rx_vxlan", 1308c2ecf20Sopenharmony_ci "rx_vxlan_err", 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci "rx_lro_pkts", 1338c2ecf20Sopenharmony_ci "rx_lro_bytes", 1348c2ecf20Sopenharmony_ci "rx_total_lro", 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci "rx_lro_aborts", 1378c2ecf20Sopenharmony_ci "rx_lro_aborts_port", 1388c2ecf20Sopenharmony_ci "rx_lro_aborts_seq", 1398c2ecf20Sopenharmony_ci "rx_lro_aborts_tsval", 1408c2ecf20Sopenharmony_ci "rx_lro_aborts_timer", 1418c2ecf20Sopenharmony_ci "rx_fwd_rate", 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci "mac_rx_total_rcvd", 1448c2ecf20Sopenharmony_ci "mac_rx_bytes", 1458c2ecf20Sopenharmony_ci "mac_rx_total_bcst", 1468c2ecf20Sopenharmony_ci "mac_rx_total_mcst", 1478c2ecf20Sopenharmony_ci "mac_rx_runts", 1488c2ecf20Sopenharmony_ci "mac_rx_ctl_packets", 1498c2ecf20Sopenharmony_ci "mac_rx_fifo_err", 1508c2ecf20Sopenharmony_ci "mac_rx_dma_drop", 1518c2ecf20Sopenharmony_ci "mac_rx_fcs_err", 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci "link_state_changes", 1548c2ecf20Sopenharmony_ci}; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci/* statistics of VF */ 1578c2ecf20Sopenharmony_cistatic const char oct_vf_stats_strings[][ETH_GSTRING_LEN] = { 1588c2ecf20Sopenharmony_ci "rx_packets", 1598c2ecf20Sopenharmony_ci "tx_packets", 1608c2ecf20Sopenharmony_ci "rx_bytes", 1618c2ecf20Sopenharmony_ci "tx_bytes", 1628c2ecf20Sopenharmony_ci "rx_errors", 1638c2ecf20Sopenharmony_ci "tx_errors", 1648c2ecf20Sopenharmony_ci "rx_dropped", 1658c2ecf20Sopenharmony_ci "tx_dropped", 1668c2ecf20Sopenharmony_ci "rx_mcast", 1678c2ecf20Sopenharmony_ci "tx_mcast", 1688c2ecf20Sopenharmony_ci "rx_bcast", 1698c2ecf20Sopenharmony_ci "tx_bcast", 1708c2ecf20Sopenharmony_ci "link_state_changes", 1718c2ecf20Sopenharmony_ci}; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci/* statistics of host tx queue */ 1748c2ecf20Sopenharmony_cistatic const char oct_iq_stats_strings[][ETH_GSTRING_LEN] = { 1758c2ecf20Sopenharmony_ci "packets", 1768c2ecf20Sopenharmony_ci "bytes", 1778c2ecf20Sopenharmony_ci "dropped", 1788c2ecf20Sopenharmony_ci "iq_busy", 1798c2ecf20Sopenharmony_ci "sgentry_sent", 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci "fw_instr_posted", 1828c2ecf20Sopenharmony_ci "fw_instr_processed", 1838c2ecf20Sopenharmony_ci "fw_instr_dropped", 1848c2ecf20Sopenharmony_ci "fw_bytes_sent", 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci "tso", 1878c2ecf20Sopenharmony_ci "vxlan", 1888c2ecf20Sopenharmony_ci "txq_restart", 1898c2ecf20Sopenharmony_ci}; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci/* statistics of host rx queue */ 1928c2ecf20Sopenharmony_cistatic const char oct_droq_stats_strings[][ETH_GSTRING_LEN] = { 1938c2ecf20Sopenharmony_ci "packets", 1948c2ecf20Sopenharmony_ci "bytes", 1958c2ecf20Sopenharmony_ci "dropped", 1968c2ecf20Sopenharmony_ci "dropped_nomem", 1978c2ecf20Sopenharmony_ci "dropped_toomany", 1988c2ecf20Sopenharmony_ci "fw_dropped", 1998c2ecf20Sopenharmony_ci "fw_pkts_received", 2008c2ecf20Sopenharmony_ci "fw_bytes_received", 2018c2ecf20Sopenharmony_ci "fw_dropped_nodispatch", 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci "vxlan", 2048c2ecf20Sopenharmony_ci "buffer_alloc_failure", 2058c2ecf20Sopenharmony_ci}; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci/* LiquidIO driver private flags */ 2088c2ecf20Sopenharmony_cistatic const char oct_priv_flags_strings[][ETH_GSTRING_LEN] = { 2098c2ecf20Sopenharmony_ci}; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci#define OCTNIC_NCMD_AUTONEG_ON 0x1 2128c2ecf20Sopenharmony_ci#define OCTNIC_NCMD_PHY_ON 0x2 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cistatic int lio_get_link_ksettings(struct net_device *netdev, 2158c2ecf20Sopenharmony_ci struct ethtool_link_ksettings *ecmd) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 2188c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 2198c2ecf20Sopenharmony_ci struct oct_link_info *linfo; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci linfo = &lio->linfo; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci ethtool_link_ksettings_zero_link_mode(ecmd, supported); 2248c2ecf20Sopenharmony_ci ethtool_link_ksettings_zero_link_mode(ecmd, advertising); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci switch (linfo->link.s.phy_type) { 2278c2ecf20Sopenharmony_ci case LIO_PHY_PORT_TP: 2288c2ecf20Sopenharmony_ci ecmd->base.port = PORT_TP; 2298c2ecf20Sopenharmony_ci ecmd->base.autoneg = AUTONEG_DISABLE; 2308c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(ecmd, supported, TP); 2318c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(ecmd, supported, Pause); 2328c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(ecmd, supported, 2338c2ecf20Sopenharmony_ci 10000baseT_Full); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(ecmd, advertising, Pause); 2368c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(ecmd, advertising, 2378c2ecf20Sopenharmony_ci 10000baseT_Full); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci break; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci case LIO_PHY_PORT_FIBRE: 2428c2ecf20Sopenharmony_ci if (linfo->link.s.if_mode == INTERFACE_MODE_XAUI || 2438c2ecf20Sopenharmony_ci linfo->link.s.if_mode == INTERFACE_MODE_RXAUI || 2448c2ecf20Sopenharmony_ci linfo->link.s.if_mode == INTERFACE_MODE_XLAUI || 2458c2ecf20Sopenharmony_ci linfo->link.s.if_mode == INTERFACE_MODE_XFI) { 2468c2ecf20Sopenharmony_ci dev_dbg(&oct->pci_dev->dev, "ecmd->base.transceiver is XCVR_EXTERNAL\n"); 2478c2ecf20Sopenharmony_ci ecmd->base.transceiver = XCVR_EXTERNAL; 2488c2ecf20Sopenharmony_ci } else { 2498c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "Unknown link interface mode: %d\n", 2508c2ecf20Sopenharmony_ci linfo->link.s.if_mode); 2518c2ecf20Sopenharmony_ci } 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci ecmd->base.port = PORT_FIBRE; 2548c2ecf20Sopenharmony_ci ecmd->base.autoneg = AUTONEG_DISABLE; 2558c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(ecmd, supported, FIBRE); 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(ecmd, supported, Pause); 2588c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(ecmd, advertising, Pause); 2598c2ecf20Sopenharmony_ci if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID || 2608c2ecf20Sopenharmony_ci oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) { 2618c2ecf20Sopenharmony_ci if (OCTEON_CN23XX_PF(oct)) { 2628c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 2638c2ecf20Sopenharmony_ci (ecmd, supported, 25000baseSR_Full); 2648c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 2658c2ecf20Sopenharmony_ci (ecmd, supported, 25000baseKR_Full); 2668c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 2678c2ecf20Sopenharmony_ci (ecmd, supported, 25000baseCR_Full); 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci if (oct->no_speed_setting == 0) { 2708c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 2718c2ecf20Sopenharmony_ci (ecmd, supported, 2728c2ecf20Sopenharmony_ci 10000baseSR_Full); 2738c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 2748c2ecf20Sopenharmony_ci (ecmd, supported, 2758c2ecf20Sopenharmony_ci 10000baseKR_Full); 2768c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 2778c2ecf20Sopenharmony_ci (ecmd, supported, 2788c2ecf20Sopenharmony_ci 10000baseCR_Full); 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci if (oct->no_speed_setting == 0) { 2828c2ecf20Sopenharmony_ci liquidio_get_speed(lio); 2838c2ecf20Sopenharmony_ci liquidio_get_fec(lio); 2848c2ecf20Sopenharmony_ci } else { 2858c2ecf20Sopenharmony_ci oct->speed_setting = 25; 2868c2ecf20Sopenharmony_ci } 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci if (oct->speed_setting == 10) { 2898c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 2908c2ecf20Sopenharmony_ci (ecmd, advertising, 2918c2ecf20Sopenharmony_ci 10000baseSR_Full); 2928c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 2938c2ecf20Sopenharmony_ci (ecmd, advertising, 2948c2ecf20Sopenharmony_ci 10000baseKR_Full); 2958c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 2968c2ecf20Sopenharmony_ci (ecmd, advertising, 2978c2ecf20Sopenharmony_ci 10000baseCR_Full); 2988c2ecf20Sopenharmony_ci } 2998c2ecf20Sopenharmony_ci if (oct->speed_setting == 25) { 3008c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3018c2ecf20Sopenharmony_ci (ecmd, advertising, 3028c2ecf20Sopenharmony_ci 25000baseSR_Full); 3038c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3048c2ecf20Sopenharmony_ci (ecmd, advertising, 3058c2ecf20Sopenharmony_ci 25000baseKR_Full); 3068c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3078c2ecf20Sopenharmony_ci (ecmd, advertising, 3088c2ecf20Sopenharmony_ci 25000baseCR_Full); 3098c2ecf20Sopenharmony_ci } 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci if (oct->no_speed_setting) 3128c2ecf20Sopenharmony_ci break; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3158c2ecf20Sopenharmony_ci (ecmd, supported, FEC_RS); 3168c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3178c2ecf20Sopenharmony_ci (ecmd, supported, FEC_NONE); 3188c2ecf20Sopenharmony_ci /*FEC_OFF*/ 3198c2ecf20Sopenharmony_ci if (oct->props[lio->ifidx].fec == 1) { 3208c2ecf20Sopenharmony_ci /* ETHTOOL_FEC_RS */ 3218c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3228c2ecf20Sopenharmony_ci (ecmd, advertising, FEC_RS); 3238c2ecf20Sopenharmony_ci } else { 3248c2ecf20Sopenharmony_ci /* ETHTOOL_FEC_OFF */ 3258c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3268c2ecf20Sopenharmony_ci (ecmd, advertising, FEC_NONE); 3278c2ecf20Sopenharmony_ci } 3288c2ecf20Sopenharmony_ci } else { /* VF */ 3298c2ecf20Sopenharmony_ci if (linfo->link.s.speed == 10000) { 3308c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3318c2ecf20Sopenharmony_ci (ecmd, supported, 3328c2ecf20Sopenharmony_ci 10000baseSR_Full); 3338c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3348c2ecf20Sopenharmony_ci (ecmd, supported, 3358c2ecf20Sopenharmony_ci 10000baseKR_Full); 3368c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3378c2ecf20Sopenharmony_ci (ecmd, supported, 3388c2ecf20Sopenharmony_ci 10000baseCR_Full); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3418c2ecf20Sopenharmony_ci (ecmd, advertising, 3428c2ecf20Sopenharmony_ci 10000baseSR_Full); 3438c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3448c2ecf20Sopenharmony_ci (ecmd, advertising, 3458c2ecf20Sopenharmony_ci 10000baseKR_Full); 3468c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3478c2ecf20Sopenharmony_ci (ecmd, advertising, 3488c2ecf20Sopenharmony_ci 10000baseCR_Full); 3498c2ecf20Sopenharmony_ci } 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci if (linfo->link.s.speed == 25000) { 3528c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3538c2ecf20Sopenharmony_ci (ecmd, supported, 3548c2ecf20Sopenharmony_ci 25000baseSR_Full); 3558c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3568c2ecf20Sopenharmony_ci (ecmd, supported, 3578c2ecf20Sopenharmony_ci 25000baseKR_Full); 3588c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3598c2ecf20Sopenharmony_ci (ecmd, supported, 3608c2ecf20Sopenharmony_ci 25000baseCR_Full); 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3638c2ecf20Sopenharmony_ci (ecmd, advertising, 3648c2ecf20Sopenharmony_ci 25000baseSR_Full); 3658c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3668c2ecf20Sopenharmony_ci (ecmd, advertising, 3678c2ecf20Sopenharmony_ci 25000baseKR_Full); 3688c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode 3698c2ecf20Sopenharmony_ci (ecmd, advertising, 3708c2ecf20Sopenharmony_ci 25000baseCR_Full); 3718c2ecf20Sopenharmony_ci } 3728c2ecf20Sopenharmony_ci } 3738c2ecf20Sopenharmony_ci } else { 3748c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(ecmd, supported, 3758c2ecf20Sopenharmony_ci 10000baseT_Full); 3768c2ecf20Sopenharmony_ci ethtool_link_ksettings_add_link_mode(ecmd, advertising, 3778c2ecf20Sopenharmony_ci 10000baseT_Full); 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci break; 3808c2ecf20Sopenharmony_ci } 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci if (linfo->link.s.link_up) { 3838c2ecf20Sopenharmony_ci ecmd->base.speed = linfo->link.s.speed; 3848c2ecf20Sopenharmony_ci ecmd->base.duplex = linfo->link.s.duplex; 3858c2ecf20Sopenharmony_ci } else { 3868c2ecf20Sopenharmony_ci ecmd->base.speed = SPEED_UNKNOWN; 3878c2ecf20Sopenharmony_ci ecmd->base.duplex = DUPLEX_UNKNOWN; 3888c2ecf20Sopenharmony_ci } 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci return 0; 3918c2ecf20Sopenharmony_ci} 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_cistatic int lio_set_link_ksettings(struct net_device *netdev, 3948c2ecf20Sopenharmony_ci const struct ethtool_link_ksettings *ecmd) 3958c2ecf20Sopenharmony_ci{ 3968c2ecf20Sopenharmony_ci const int speed = ecmd->base.speed; 3978c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 3988c2ecf20Sopenharmony_ci struct oct_link_info *linfo; 3998c2ecf20Sopenharmony_ci struct octeon_device *oct; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci oct = lio->oct_dev; 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci linfo = &lio->linfo; 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci if (!(oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID || 4068c2ecf20Sopenharmony_ci oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID)) 4078c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci if (oct->no_speed_setting) { 4108c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "%s: Changing speed is not supported\n", 4118c2ecf20Sopenharmony_ci __func__); 4128c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 4138c2ecf20Sopenharmony_ci } 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci if ((ecmd->base.duplex != DUPLEX_UNKNOWN && 4168c2ecf20Sopenharmony_ci ecmd->base.duplex != linfo->link.s.duplex) || 4178c2ecf20Sopenharmony_ci ecmd->base.autoneg != AUTONEG_DISABLE || 4188c2ecf20Sopenharmony_ci (ecmd->base.speed != 10000 && ecmd->base.speed != 25000 && 4198c2ecf20Sopenharmony_ci ecmd->base.speed != SPEED_UNKNOWN)) 4208c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci if ((oct->speed_boot == speed / 1000) && 4238c2ecf20Sopenharmony_ci oct->speed_boot == oct->speed_setting) 4248c2ecf20Sopenharmony_ci return 0; 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci liquidio_set_speed(lio, speed / 1000); 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci dev_dbg(&oct->pci_dev->dev, "Port speed is set to %dG\n", 4298c2ecf20Sopenharmony_ci oct->speed_setting); 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci return 0; 4328c2ecf20Sopenharmony_ci} 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_cistatic void 4358c2ecf20Sopenharmony_cilio_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) 4368c2ecf20Sopenharmony_ci{ 4378c2ecf20Sopenharmony_ci struct lio *lio; 4388c2ecf20Sopenharmony_ci struct octeon_device *oct; 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci lio = GET_LIO(netdev); 4418c2ecf20Sopenharmony_ci oct = lio->oct_dev; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); 4448c2ecf20Sopenharmony_ci strcpy(drvinfo->driver, "liquidio"); 4458c2ecf20Sopenharmony_ci strncpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version, 4468c2ecf20Sopenharmony_ci ETHTOOL_FWVERS_LEN); 4478c2ecf20Sopenharmony_ci strncpy(drvinfo->bus_info, pci_name(oct->pci_dev), 32); 4488c2ecf20Sopenharmony_ci} 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_cistatic void 4518c2ecf20Sopenharmony_cilio_get_vf_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) 4528c2ecf20Sopenharmony_ci{ 4538c2ecf20Sopenharmony_ci struct octeon_device *oct; 4548c2ecf20Sopenharmony_ci struct lio *lio; 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci lio = GET_LIO(netdev); 4578c2ecf20Sopenharmony_ci oct = lio->oct_dev; 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); 4608c2ecf20Sopenharmony_ci strcpy(drvinfo->driver, "liquidio_vf"); 4618c2ecf20Sopenharmony_ci strncpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version, 4628c2ecf20Sopenharmony_ci ETHTOOL_FWVERS_LEN); 4638c2ecf20Sopenharmony_ci strncpy(drvinfo->bus_info, pci_name(oct->pci_dev), 32); 4648c2ecf20Sopenharmony_ci} 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_cistatic int 4678c2ecf20Sopenharmony_cilio_send_queue_count_update(struct net_device *netdev, uint32_t num_queues) 4688c2ecf20Sopenharmony_ci{ 4698c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 4708c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 4718c2ecf20Sopenharmony_ci struct octnic_ctrl_pkt nctrl; 4728c2ecf20Sopenharmony_ci int ret = 0; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci nctrl.ncmd.u64 = 0; 4778c2ecf20Sopenharmony_ci nctrl.ncmd.s.cmd = OCTNET_CMD_QUEUE_COUNT_CTL; 4788c2ecf20Sopenharmony_ci nctrl.ncmd.s.param1 = num_queues; 4798c2ecf20Sopenharmony_ci nctrl.ncmd.s.param2 = num_queues; 4808c2ecf20Sopenharmony_ci nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; 4818c2ecf20Sopenharmony_ci nctrl.netpndev = (u64)netdev; 4828c2ecf20Sopenharmony_ci nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 4858c2ecf20Sopenharmony_ci if (ret) { 4868c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "Failed to send Queue reset command (ret: 0x%x)\n", 4878c2ecf20Sopenharmony_ci ret); 4888c2ecf20Sopenharmony_ci return -1; 4898c2ecf20Sopenharmony_ci } 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci return 0; 4928c2ecf20Sopenharmony_ci} 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_cistatic void 4958c2ecf20Sopenharmony_cilio_ethtool_get_channels(struct net_device *dev, 4968c2ecf20Sopenharmony_ci struct ethtool_channels *channel) 4978c2ecf20Sopenharmony_ci{ 4988c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(dev); 4998c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 5008c2ecf20Sopenharmony_ci u32 max_rx = 0, max_tx = 0, tx_count = 0, rx_count = 0; 5018c2ecf20Sopenharmony_ci u32 combined_count = 0, max_combined = 0; 5028c2ecf20Sopenharmony_ci 5038c2ecf20Sopenharmony_ci if (OCTEON_CN6XXX(oct)) { 5048c2ecf20Sopenharmony_ci struct octeon_config *conf6x = CHIP_CONF(oct, cn6xxx); 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci max_rx = CFG_GET_OQ_MAX_Q(conf6x); 5078c2ecf20Sopenharmony_ci max_tx = CFG_GET_IQ_MAX_Q(conf6x); 5088c2ecf20Sopenharmony_ci rx_count = CFG_GET_NUM_RXQS_NIC_IF(conf6x, lio->ifidx); 5098c2ecf20Sopenharmony_ci tx_count = CFG_GET_NUM_TXQS_NIC_IF(conf6x, lio->ifidx); 5108c2ecf20Sopenharmony_ci } else if (OCTEON_CN23XX_PF(oct)) { 5118c2ecf20Sopenharmony_ci if (oct->sriov_info.sriov_enabled) { 5128c2ecf20Sopenharmony_ci max_combined = lio->linfo.num_txpciq; 5138c2ecf20Sopenharmony_ci } else { 5148c2ecf20Sopenharmony_ci struct octeon_config *conf23_pf = 5158c2ecf20Sopenharmony_ci CHIP_CONF(oct, cn23xx_pf); 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci max_combined = CFG_GET_IQ_MAX_Q(conf23_pf); 5188c2ecf20Sopenharmony_ci } 5198c2ecf20Sopenharmony_ci combined_count = oct->num_iqs; 5208c2ecf20Sopenharmony_ci } else if (OCTEON_CN23XX_VF(oct)) { 5218c2ecf20Sopenharmony_ci u64 reg_val = 0ULL; 5228c2ecf20Sopenharmony_ci u64 ctrl = CN23XX_VF_SLI_IQ_PKT_CONTROL64(0); 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci reg_val = octeon_read_csr64(oct, ctrl); 5258c2ecf20Sopenharmony_ci reg_val = reg_val >> CN23XX_PKT_INPUT_CTL_RPVF_POS; 5268c2ecf20Sopenharmony_ci max_combined = reg_val & CN23XX_PKT_INPUT_CTL_RPVF_MASK; 5278c2ecf20Sopenharmony_ci combined_count = oct->num_iqs; 5288c2ecf20Sopenharmony_ci } 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci channel->max_rx = max_rx; 5318c2ecf20Sopenharmony_ci channel->max_tx = max_tx; 5328c2ecf20Sopenharmony_ci channel->max_combined = max_combined; 5338c2ecf20Sopenharmony_ci channel->rx_count = rx_count; 5348c2ecf20Sopenharmony_ci channel->tx_count = tx_count; 5358c2ecf20Sopenharmony_ci channel->combined_count = combined_count; 5368c2ecf20Sopenharmony_ci} 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_cistatic int 5398c2ecf20Sopenharmony_cilio_irq_reallocate_irqs(struct octeon_device *oct, uint32_t num_ioqs) 5408c2ecf20Sopenharmony_ci{ 5418c2ecf20Sopenharmony_ci struct msix_entry *msix_entries; 5428c2ecf20Sopenharmony_ci int num_msix_irqs = 0; 5438c2ecf20Sopenharmony_ci int i; 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci if (!oct->msix_on) 5468c2ecf20Sopenharmony_ci return 0; 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ci /* Disable the input and output queues now. No more packets will 5498c2ecf20Sopenharmony_ci * arrive from Octeon. 5508c2ecf20Sopenharmony_ci */ 5518c2ecf20Sopenharmony_ci oct->fn_list.disable_interrupt(oct, OCTEON_ALL_INTR); 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci if (oct->msix_on) { 5548c2ecf20Sopenharmony_ci if (OCTEON_CN23XX_PF(oct)) 5558c2ecf20Sopenharmony_ci num_msix_irqs = oct->num_msix_irqs - 1; 5568c2ecf20Sopenharmony_ci else if (OCTEON_CN23XX_VF(oct)) 5578c2ecf20Sopenharmony_ci num_msix_irqs = oct->num_msix_irqs; 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci msix_entries = (struct msix_entry *)oct->msix_entries; 5608c2ecf20Sopenharmony_ci for (i = 0; i < num_msix_irqs; i++) { 5618c2ecf20Sopenharmony_ci if (oct->ioq_vector[i].vector) { 5628c2ecf20Sopenharmony_ci /* clear the affinity_cpumask */ 5638c2ecf20Sopenharmony_ci irq_set_affinity_hint(msix_entries[i].vector, 5648c2ecf20Sopenharmony_ci NULL); 5658c2ecf20Sopenharmony_ci free_irq(msix_entries[i].vector, 5668c2ecf20Sopenharmony_ci &oct->ioq_vector[i]); 5678c2ecf20Sopenharmony_ci oct->ioq_vector[i].vector = 0; 5688c2ecf20Sopenharmony_ci } 5698c2ecf20Sopenharmony_ci } 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci /* non-iov vector's argument is oct struct */ 5728c2ecf20Sopenharmony_ci if (OCTEON_CN23XX_PF(oct)) 5738c2ecf20Sopenharmony_ci free_irq(msix_entries[i].vector, oct); 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci pci_disable_msix(oct->pci_dev); 5768c2ecf20Sopenharmony_ci kfree(oct->msix_entries); 5778c2ecf20Sopenharmony_ci oct->msix_entries = NULL; 5788c2ecf20Sopenharmony_ci } 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci kfree(oct->irq_name_storage); 5818c2ecf20Sopenharmony_ci oct->irq_name_storage = NULL; 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci if (octeon_allocate_ioq_vector(oct, num_ioqs)) { 5848c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "OCTEON: ioq vector allocation failed\n"); 5858c2ecf20Sopenharmony_ci return -1; 5868c2ecf20Sopenharmony_ci } 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci if (octeon_setup_interrupt(oct, num_ioqs)) { 5898c2ecf20Sopenharmony_ci dev_info(&oct->pci_dev->dev, "Setup interrupt failed\n"); 5908c2ecf20Sopenharmony_ci return -1; 5918c2ecf20Sopenharmony_ci } 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci /* Enable Octeon device interrupts */ 5948c2ecf20Sopenharmony_ci oct->fn_list.enable_interrupt(oct, OCTEON_ALL_INTR); 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci return 0; 5978c2ecf20Sopenharmony_ci} 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_cistatic int 6008c2ecf20Sopenharmony_cilio_ethtool_set_channels(struct net_device *dev, 6018c2ecf20Sopenharmony_ci struct ethtool_channels *channel) 6028c2ecf20Sopenharmony_ci{ 6038c2ecf20Sopenharmony_ci u32 combined_count, max_combined; 6048c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(dev); 6058c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 6068c2ecf20Sopenharmony_ci int stopped = 0; 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci if (strcmp(oct->fw_info.liquidio_firmware_version, "1.6.1") < 0) { 6098c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "Minimum firmware version required is 1.6.1\n"); 6108c2ecf20Sopenharmony_ci return -EINVAL; 6118c2ecf20Sopenharmony_ci } 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci if (!channel->combined_count || channel->other_count || 6148c2ecf20Sopenharmony_ci channel->rx_count || channel->tx_count) 6158c2ecf20Sopenharmony_ci return -EINVAL; 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci combined_count = channel->combined_count; 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_ci if (OCTEON_CN23XX_PF(oct)) { 6208c2ecf20Sopenharmony_ci if (oct->sriov_info.sriov_enabled) { 6218c2ecf20Sopenharmony_ci max_combined = lio->linfo.num_txpciq; 6228c2ecf20Sopenharmony_ci } else { 6238c2ecf20Sopenharmony_ci struct octeon_config *conf23_pf = 6248c2ecf20Sopenharmony_ci CHIP_CONF(oct, 6258c2ecf20Sopenharmony_ci cn23xx_pf); 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci max_combined = 6288c2ecf20Sopenharmony_ci CFG_GET_IQ_MAX_Q(conf23_pf); 6298c2ecf20Sopenharmony_ci } 6308c2ecf20Sopenharmony_ci } else if (OCTEON_CN23XX_VF(oct)) { 6318c2ecf20Sopenharmony_ci u64 reg_val = 0ULL; 6328c2ecf20Sopenharmony_ci u64 ctrl = CN23XX_VF_SLI_IQ_PKT_CONTROL64(0); 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci reg_val = octeon_read_csr64(oct, ctrl); 6358c2ecf20Sopenharmony_ci reg_val = reg_val >> CN23XX_PKT_INPUT_CTL_RPVF_POS; 6368c2ecf20Sopenharmony_ci max_combined = reg_val & CN23XX_PKT_INPUT_CTL_RPVF_MASK; 6378c2ecf20Sopenharmony_ci } else { 6388c2ecf20Sopenharmony_ci return -EINVAL; 6398c2ecf20Sopenharmony_ci } 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci if (combined_count > max_combined || combined_count < 1) 6428c2ecf20Sopenharmony_ci return -EINVAL; 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci if (combined_count == oct->num_iqs) 6458c2ecf20Sopenharmony_ci return 0; 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ci ifstate_set(lio, LIO_IFSTATE_RESETTING); 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci if (netif_running(dev)) { 6508c2ecf20Sopenharmony_ci dev->netdev_ops->ndo_stop(dev); 6518c2ecf20Sopenharmony_ci stopped = 1; 6528c2ecf20Sopenharmony_ci } 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci if (lio_reset_queues(dev, combined_count)) 6558c2ecf20Sopenharmony_ci return -EINVAL; 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci if (stopped) 6588c2ecf20Sopenharmony_ci dev->netdev_ops->ndo_open(dev); 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci ifstate_reset(lio, LIO_IFSTATE_RESETTING); 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ci return 0; 6638c2ecf20Sopenharmony_ci} 6648c2ecf20Sopenharmony_ci 6658c2ecf20Sopenharmony_cistatic int lio_get_eeprom_len(struct net_device *netdev) 6668c2ecf20Sopenharmony_ci{ 6678c2ecf20Sopenharmony_ci u8 buf[192]; 6688c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 6698c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 6708c2ecf20Sopenharmony_ci struct octeon_board_info *board_info; 6718c2ecf20Sopenharmony_ci int len; 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_ci board_info = (struct octeon_board_info *)(&oct_dev->boardinfo); 6748c2ecf20Sopenharmony_ci len = sprintf(buf, "boardname:%s serialnum:%s maj:%lld min:%lld\n", 6758c2ecf20Sopenharmony_ci board_info->name, board_info->serial_number, 6768c2ecf20Sopenharmony_ci board_info->major, board_info->minor); 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_ci return len; 6798c2ecf20Sopenharmony_ci} 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_cistatic int 6828c2ecf20Sopenharmony_cilio_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, 6838c2ecf20Sopenharmony_ci u8 *bytes) 6848c2ecf20Sopenharmony_ci{ 6858c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 6868c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 6878c2ecf20Sopenharmony_ci struct octeon_board_info *board_info; 6888c2ecf20Sopenharmony_ci 6898c2ecf20Sopenharmony_ci if (eeprom->offset) 6908c2ecf20Sopenharmony_ci return -EINVAL; 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci eeprom->magic = oct_dev->pci_dev->vendor; 6938c2ecf20Sopenharmony_ci board_info = (struct octeon_board_info *)(&oct_dev->boardinfo); 6948c2ecf20Sopenharmony_ci sprintf((char *)bytes, 6958c2ecf20Sopenharmony_ci "boardname:%s serialnum:%s maj:%lld min:%lld\n", 6968c2ecf20Sopenharmony_ci board_info->name, board_info->serial_number, 6978c2ecf20Sopenharmony_ci board_info->major, board_info->minor); 6988c2ecf20Sopenharmony_ci 6998c2ecf20Sopenharmony_ci return 0; 7008c2ecf20Sopenharmony_ci} 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_cistatic int octnet_gpio_access(struct net_device *netdev, int addr, int val) 7038c2ecf20Sopenharmony_ci{ 7048c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 7058c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 7068c2ecf20Sopenharmony_ci struct octnic_ctrl_pkt nctrl; 7078c2ecf20Sopenharmony_ci int ret = 0; 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci nctrl.ncmd.u64 = 0; 7128c2ecf20Sopenharmony_ci nctrl.ncmd.s.cmd = OCTNET_CMD_GPIO_ACCESS; 7138c2ecf20Sopenharmony_ci nctrl.ncmd.s.param1 = addr; 7148c2ecf20Sopenharmony_ci nctrl.ncmd.s.param2 = val; 7158c2ecf20Sopenharmony_ci nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; 7168c2ecf20Sopenharmony_ci nctrl.netpndev = (u64)netdev; 7178c2ecf20Sopenharmony_ci nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_ci ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 7208c2ecf20Sopenharmony_ci if (ret) { 7218c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, 7228c2ecf20Sopenharmony_ci "Failed to configure gpio value, ret=%d\n", ret); 7238c2ecf20Sopenharmony_ci return -EINVAL; 7248c2ecf20Sopenharmony_ci } 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci return 0; 7278c2ecf20Sopenharmony_ci} 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_cistatic int octnet_id_active(struct net_device *netdev, int val) 7308c2ecf20Sopenharmony_ci{ 7318c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 7328c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 7338c2ecf20Sopenharmony_ci struct octnic_ctrl_pkt nctrl; 7348c2ecf20Sopenharmony_ci int ret = 0; 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_ci nctrl.ncmd.u64 = 0; 7398c2ecf20Sopenharmony_ci nctrl.ncmd.s.cmd = OCTNET_CMD_ID_ACTIVE; 7408c2ecf20Sopenharmony_ci nctrl.ncmd.s.param1 = val; 7418c2ecf20Sopenharmony_ci nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; 7428c2ecf20Sopenharmony_ci nctrl.netpndev = (u64)netdev; 7438c2ecf20Sopenharmony_ci nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_ci ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 7468c2ecf20Sopenharmony_ci if (ret) { 7478c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, 7488c2ecf20Sopenharmony_ci "Failed to configure gpio value, ret=%d\n", ret); 7498c2ecf20Sopenharmony_ci return -EINVAL; 7508c2ecf20Sopenharmony_ci } 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci return 0; 7538c2ecf20Sopenharmony_ci} 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_ci/* This routine provides PHY access routines for 7568c2ecf20Sopenharmony_ci * mdio clause45 . 7578c2ecf20Sopenharmony_ci */ 7588c2ecf20Sopenharmony_cistatic int 7598c2ecf20Sopenharmony_cioctnet_mdio45_access(struct lio *lio, int op, int loc, int *value) 7608c2ecf20Sopenharmony_ci{ 7618c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 7628c2ecf20Sopenharmony_ci struct octeon_soft_command *sc; 7638c2ecf20Sopenharmony_ci struct oct_mdio_cmd_resp *mdio_cmd_rsp; 7648c2ecf20Sopenharmony_ci struct oct_mdio_cmd *mdio_cmd; 7658c2ecf20Sopenharmony_ci int retval = 0; 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci sc = (struct octeon_soft_command *) 7688c2ecf20Sopenharmony_ci octeon_alloc_soft_command(oct_dev, 7698c2ecf20Sopenharmony_ci sizeof(struct oct_mdio_cmd), 7708c2ecf20Sopenharmony_ci sizeof(struct oct_mdio_cmd_resp), 0); 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_ci if (!sc) 7738c2ecf20Sopenharmony_ci return -ENOMEM; 7748c2ecf20Sopenharmony_ci 7758c2ecf20Sopenharmony_ci mdio_cmd_rsp = (struct oct_mdio_cmd_resp *)sc->virtrptr; 7768c2ecf20Sopenharmony_ci mdio_cmd = (struct oct_mdio_cmd *)sc->virtdptr; 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_ci mdio_cmd->op = op; 7798c2ecf20Sopenharmony_ci mdio_cmd->mdio_addr = loc; 7808c2ecf20Sopenharmony_ci if (op) 7818c2ecf20Sopenharmony_ci mdio_cmd->value1 = *value; 7828c2ecf20Sopenharmony_ci octeon_swap_8B_data((u64 *)mdio_cmd, sizeof(struct oct_mdio_cmd) / 8); 7838c2ecf20Sopenharmony_ci 7848c2ecf20Sopenharmony_ci sc->iq_no = lio->linfo.txpciq[0].s.q_no; 7858c2ecf20Sopenharmony_ci 7868c2ecf20Sopenharmony_ci octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, OPCODE_NIC_MDIO45, 7878c2ecf20Sopenharmony_ci 0, 0, 0); 7888c2ecf20Sopenharmony_ci 7898c2ecf20Sopenharmony_ci init_completion(&sc->complete); 7908c2ecf20Sopenharmony_ci sc->sc_status = OCTEON_REQUEST_PENDING; 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_ci retval = octeon_send_soft_command(oct_dev, sc); 7938c2ecf20Sopenharmony_ci if (retval == IQ_SEND_FAILED) { 7948c2ecf20Sopenharmony_ci dev_err(&oct_dev->pci_dev->dev, 7958c2ecf20Sopenharmony_ci "octnet_mdio45_access instruction failed status: %x\n", 7968c2ecf20Sopenharmony_ci retval); 7978c2ecf20Sopenharmony_ci octeon_free_soft_command(oct_dev, sc); 7988c2ecf20Sopenharmony_ci return -EBUSY; 7998c2ecf20Sopenharmony_ci } else { 8008c2ecf20Sopenharmony_ci /* Sleep on a wait queue till the cond flag indicates that the 8018c2ecf20Sopenharmony_ci * response arrived 8028c2ecf20Sopenharmony_ci */ 8038c2ecf20Sopenharmony_ci retval = wait_for_sc_completion_timeout(oct_dev, sc, 0); 8048c2ecf20Sopenharmony_ci if (retval) 8058c2ecf20Sopenharmony_ci return retval; 8068c2ecf20Sopenharmony_ci 8078c2ecf20Sopenharmony_ci retval = mdio_cmd_rsp->status; 8088c2ecf20Sopenharmony_ci if (retval) { 8098c2ecf20Sopenharmony_ci dev_err(&oct_dev->pci_dev->dev, 8108c2ecf20Sopenharmony_ci "octnet mdio45 access failed: %x\n", retval); 8118c2ecf20Sopenharmony_ci WRITE_ONCE(sc->caller_is_done, true); 8128c2ecf20Sopenharmony_ci return -EBUSY; 8138c2ecf20Sopenharmony_ci } 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci octeon_swap_8B_data((u64 *)(&mdio_cmd_rsp->resp), 8168c2ecf20Sopenharmony_ci sizeof(struct oct_mdio_cmd) / 8); 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci if (!op) 8198c2ecf20Sopenharmony_ci *value = mdio_cmd_rsp->resp.value1; 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci WRITE_ONCE(sc->caller_is_done, true); 8228c2ecf20Sopenharmony_ci } 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_ci return retval; 8258c2ecf20Sopenharmony_ci} 8268c2ecf20Sopenharmony_ci 8278c2ecf20Sopenharmony_cistatic int lio_set_phys_id(struct net_device *netdev, 8288c2ecf20Sopenharmony_ci enum ethtool_phys_id_state state) 8298c2ecf20Sopenharmony_ci{ 8308c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 8318c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 8328c2ecf20Sopenharmony_ci struct oct_link_info *linfo; 8338c2ecf20Sopenharmony_ci int value, ret; 8348c2ecf20Sopenharmony_ci u32 cur_ver; 8358c2ecf20Sopenharmony_ci 8368c2ecf20Sopenharmony_ci linfo = &lio->linfo; 8378c2ecf20Sopenharmony_ci cur_ver = OCT_FW_VER(oct->fw_info.ver.maj, 8388c2ecf20Sopenharmony_ci oct->fw_info.ver.min, 8398c2ecf20Sopenharmony_ci oct->fw_info.ver.rev); 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_ci switch (state) { 8428c2ecf20Sopenharmony_ci case ETHTOOL_ID_ACTIVE: 8438c2ecf20Sopenharmony_ci if (oct->chip_id == OCTEON_CN66XX) { 8448c2ecf20Sopenharmony_ci octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG, 8458c2ecf20Sopenharmony_ci VITESSE_PHY_GPIO_DRIVEON); 8468c2ecf20Sopenharmony_ci return 2; 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci } else if (oct->chip_id == OCTEON_CN68XX) { 8498c2ecf20Sopenharmony_ci /* Save the current LED settings */ 8508c2ecf20Sopenharmony_ci ret = octnet_mdio45_access(lio, 0, 8518c2ecf20Sopenharmony_ci LIO68XX_LED_BEACON_ADDR, 8528c2ecf20Sopenharmony_ci &lio->phy_beacon_val); 8538c2ecf20Sopenharmony_ci if (ret) 8548c2ecf20Sopenharmony_ci return ret; 8558c2ecf20Sopenharmony_ci 8568c2ecf20Sopenharmony_ci ret = octnet_mdio45_access(lio, 0, 8578c2ecf20Sopenharmony_ci LIO68XX_LED_CTRL_ADDR, 8588c2ecf20Sopenharmony_ci &lio->led_ctrl_val); 8598c2ecf20Sopenharmony_ci if (ret) 8608c2ecf20Sopenharmony_ci return ret; 8618c2ecf20Sopenharmony_ci 8628c2ecf20Sopenharmony_ci /* Configure Beacon values */ 8638c2ecf20Sopenharmony_ci value = LIO68XX_LED_BEACON_CFGON; 8648c2ecf20Sopenharmony_ci ret = octnet_mdio45_access(lio, 1, 8658c2ecf20Sopenharmony_ci LIO68XX_LED_BEACON_ADDR, 8668c2ecf20Sopenharmony_ci &value); 8678c2ecf20Sopenharmony_ci if (ret) 8688c2ecf20Sopenharmony_ci return ret; 8698c2ecf20Sopenharmony_ci 8708c2ecf20Sopenharmony_ci value = LIO68XX_LED_CTRL_CFGON; 8718c2ecf20Sopenharmony_ci ret = octnet_mdio45_access(lio, 1, 8728c2ecf20Sopenharmony_ci LIO68XX_LED_CTRL_ADDR, 8738c2ecf20Sopenharmony_ci &value); 8748c2ecf20Sopenharmony_ci if (ret) 8758c2ecf20Sopenharmony_ci return ret; 8768c2ecf20Sopenharmony_ci } else if (oct->chip_id == OCTEON_CN23XX_PF_VID) { 8778c2ecf20Sopenharmony_ci octnet_id_active(netdev, LED_IDENTIFICATION_ON); 8788c2ecf20Sopenharmony_ci if (linfo->link.s.phy_type == LIO_PHY_PORT_TP && 8798c2ecf20Sopenharmony_ci cur_ver > OCT_FW_VER(1, 7, 2)) 8808c2ecf20Sopenharmony_ci return 2; 8818c2ecf20Sopenharmony_ci else 8828c2ecf20Sopenharmony_ci return 0; 8838c2ecf20Sopenharmony_ci } else { 8848c2ecf20Sopenharmony_ci return -EINVAL; 8858c2ecf20Sopenharmony_ci } 8868c2ecf20Sopenharmony_ci break; 8878c2ecf20Sopenharmony_ci 8888c2ecf20Sopenharmony_ci case ETHTOOL_ID_ON: 8898c2ecf20Sopenharmony_ci if (oct->chip_id == OCTEON_CN23XX_PF_VID && 8908c2ecf20Sopenharmony_ci linfo->link.s.phy_type == LIO_PHY_PORT_TP && 8918c2ecf20Sopenharmony_ci cur_ver > OCT_FW_VER(1, 7, 2)) 8928c2ecf20Sopenharmony_ci octnet_id_active(netdev, LED_IDENTIFICATION_ON); 8938c2ecf20Sopenharmony_ci else if (oct->chip_id == OCTEON_CN66XX) 8948c2ecf20Sopenharmony_ci octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG, 8958c2ecf20Sopenharmony_ci VITESSE_PHY_GPIO_HIGH); 8968c2ecf20Sopenharmony_ci else 8978c2ecf20Sopenharmony_ci return -EINVAL; 8988c2ecf20Sopenharmony_ci 8998c2ecf20Sopenharmony_ci break; 9008c2ecf20Sopenharmony_ci 9018c2ecf20Sopenharmony_ci case ETHTOOL_ID_OFF: 9028c2ecf20Sopenharmony_ci if (oct->chip_id == OCTEON_CN23XX_PF_VID && 9038c2ecf20Sopenharmony_ci linfo->link.s.phy_type == LIO_PHY_PORT_TP && 9048c2ecf20Sopenharmony_ci cur_ver > OCT_FW_VER(1, 7, 2)) 9058c2ecf20Sopenharmony_ci octnet_id_active(netdev, LED_IDENTIFICATION_OFF); 9068c2ecf20Sopenharmony_ci else if (oct->chip_id == OCTEON_CN66XX) 9078c2ecf20Sopenharmony_ci octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG, 9088c2ecf20Sopenharmony_ci VITESSE_PHY_GPIO_LOW); 9098c2ecf20Sopenharmony_ci else 9108c2ecf20Sopenharmony_ci return -EINVAL; 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci break; 9138c2ecf20Sopenharmony_ci 9148c2ecf20Sopenharmony_ci case ETHTOOL_ID_INACTIVE: 9158c2ecf20Sopenharmony_ci if (oct->chip_id == OCTEON_CN66XX) { 9168c2ecf20Sopenharmony_ci octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG, 9178c2ecf20Sopenharmony_ci VITESSE_PHY_GPIO_DRIVEOFF); 9188c2ecf20Sopenharmony_ci } else if (oct->chip_id == OCTEON_CN68XX) { 9198c2ecf20Sopenharmony_ci /* Restore LED settings */ 9208c2ecf20Sopenharmony_ci ret = octnet_mdio45_access(lio, 1, 9218c2ecf20Sopenharmony_ci LIO68XX_LED_CTRL_ADDR, 9228c2ecf20Sopenharmony_ci &lio->led_ctrl_val); 9238c2ecf20Sopenharmony_ci if (ret) 9248c2ecf20Sopenharmony_ci return ret; 9258c2ecf20Sopenharmony_ci 9268c2ecf20Sopenharmony_ci ret = octnet_mdio45_access(lio, 1, 9278c2ecf20Sopenharmony_ci LIO68XX_LED_BEACON_ADDR, 9288c2ecf20Sopenharmony_ci &lio->phy_beacon_val); 9298c2ecf20Sopenharmony_ci if (ret) 9308c2ecf20Sopenharmony_ci return ret; 9318c2ecf20Sopenharmony_ci } else if (oct->chip_id == OCTEON_CN23XX_PF_VID) { 9328c2ecf20Sopenharmony_ci octnet_id_active(netdev, LED_IDENTIFICATION_OFF); 9338c2ecf20Sopenharmony_ci 9348c2ecf20Sopenharmony_ci return 0; 9358c2ecf20Sopenharmony_ci } else { 9368c2ecf20Sopenharmony_ci return -EINVAL; 9378c2ecf20Sopenharmony_ci } 9388c2ecf20Sopenharmony_ci break; 9398c2ecf20Sopenharmony_ci 9408c2ecf20Sopenharmony_ci default: 9418c2ecf20Sopenharmony_ci return -EINVAL; 9428c2ecf20Sopenharmony_ci } 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_ci return 0; 9458c2ecf20Sopenharmony_ci} 9468c2ecf20Sopenharmony_ci 9478c2ecf20Sopenharmony_cistatic void 9488c2ecf20Sopenharmony_cilio_ethtool_get_ringparam(struct net_device *netdev, 9498c2ecf20Sopenharmony_ci struct ethtool_ringparam *ering) 9508c2ecf20Sopenharmony_ci{ 9518c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 9528c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 9538c2ecf20Sopenharmony_ci u32 tx_max_pending = 0, rx_max_pending = 0, tx_pending = 0, 9548c2ecf20Sopenharmony_ci rx_pending = 0; 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_ci if (ifstate_check(lio, LIO_IFSTATE_RESETTING)) 9578c2ecf20Sopenharmony_ci return; 9588c2ecf20Sopenharmony_ci 9598c2ecf20Sopenharmony_ci if (OCTEON_CN6XXX(oct)) { 9608c2ecf20Sopenharmony_ci struct octeon_config *conf6x = CHIP_CONF(oct, cn6xxx); 9618c2ecf20Sopenharmony_ci 9628c2ecf20Sopenharmony_ci tx_max_pending = CN6XXX_MAX_IQ_DESCRIPTORS; 9638c2ecf20Sopenharmony_ci rx_max_pending = CN6XXX_MAX_OQ_DESCRIPTORS; 9648c2ecf20Sopenharmony_ci rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf6x, lio->ifidx); 9658c2ecf20Sopenharmony_ci tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf6x, lio->ifidx); 9668c2ecf20Sopenharmony_ci } else if (OCTEON_CN23XX_PF(oct) || OCTEON_CN23XX_VF(oct)) { 9678c2ecf20Sopenharmony_ci tx_max_pending = CN23XX_MAX_IQ_DESCRIPTORS; 9688c2ecf20Sopenharmony_ci rx_max_pending = CN23XX_MAX_OQ_DESCRIPTORS; 9698c2ecf20Sopenharmony_ci rx_pending = oct->droq[0]->max_count; 9708c2ecf20Sopenharmony_ci tx_pending = oct->instr_queue[0]->max_count; 9718c2ecf20Sopenharmony_ci } 9728c2ecf20Sopenharmony_ci 9738c2ecf20Sopenharmony_ci ering->tx_pending = tx_pending; 9748c2ecf20Sopenharmony_ci ering->tx_max_pending = tx_max_pending; 9758c2ecf20Sopenharmony_ci ering->rx_pending = rx_pending; 9768c2ecf20Sopenharmony_ci ering->rx_max_pending = rx_max_pending; 9778c2ecf20Sopenharmony_ci ering->rx_mini_pending = 0; 9788c2ecf20Sopenharmony_ci ering->rx_jumbo_pending = 0; 9798c2ecf20Sopenharmony_ci ering->rx_mini_max_pending = 0; 9808c2ecf20Sopenharmony_ci ering->rx_jumbo_max_pending = 0; 9818c2ecf20Sopenharmony_ci} 9828c2ecf20Sopenharmony_ci 9838c2ecf20Sopenharmony_cistatic int lio_23xx_reconfigure_queue_count(struct lio *lio) 9848c2ecf20Sopenharmony_ci{ 9858c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 9868c2ecf20Sopenharmony_ci u32 resp_size, data_size; 9878c2ecf20Sopenharmony_ci struct liquidio_if_cfg_resp *resp; 9888c2ecf20Sopenharmony_ci struct octeon_soft_command *sc; 9898c2ecf20Sopenharmony_ci union oct_nic_if_cfg if_cfg; 9908c2ecf20Sopenharmony_ci struct lio_version *vdata; 9918c2ecf20Sopenharmony_ci u32 ifidx_or_pfnum; 9928c2ecf20Sopenharmony_ci int retval; 9938c2ecf20Sopenharmony_ci int j; 9948c2ecf20Sopenharmony_ci 9958c2ecf20Sopenharmony_ci resp_size = sizeof(struct liquidio_if_cfg_resp); 9968c2ecf20Sopenharmony_ci data_size = sizeof(struct lio_version); 9978c2ecf20Sopenharmony_ci sc = (struct octeon_soft_command *) 9988c2ecf20Sopenharmony_ci octeon_alloc_soft_command(oct, data_size, 9998c2ecf20Sopenharmony_ci resp_size, 0); 10008c2ecf20Sopenharmony_ci if (!sc) { 10018c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "%s: Failed to allocate soft command\n", 10028c2ecf20Sopenharmony_ci __func__); 10038c2ecf20Sopenharmony_ci return -1; 10048c2ecf20Sopenharmony_ci } 10058c2ecf20Sopenharmony_ci 10068c2ecf20Sopenharmony_ci resp = (struct liquidio_if_cfg_resp *)sc->virtrptr; 10078c2ecf20Sopenharmony_ci vdata = (struct lio_version *)sc->virtdptr; 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci vdata->major = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MAJOR_VERSION); 10108c2ecf20Sopenharmony_ci vdata->minor = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MINOR_VERSION); 10118c2ecf20Sopenharmony_ci vdata->micro = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MICRO_VERSION); 10128c2ecf20Sopenharmony_ci 10138c2ecf20Sopenharmony_ci ifidx_or_pfnum = oct->pf_num; 10148c2ecf20Sopenharmony_ci 10158c2ecf20Sopenharmony_ci if_cfg.u64 = 0; 10168c2ecf20Sopenharmony_ci if_cfg.s.num_iqueues = oct->sriov_info.num_pf_rings; 10178c2ecf20Sopenharmony_ci if_cfg.s.num_oqueues = oct->sriov_info.num_pf_rings; 10188c2ecf20Sopenharmony_ci if_cfg.s.base_queue = oct->sriov_info.pf_srn; 10198c2ecf20Sopenharmony_ci if_cfg.s.gmx_port_id = oct->pf_num; 10208c2ecf20Sopenharmony_ci 10218c2ecf20Sopenharmony_ci sc->iq_no = 0; 10228c2ecf20Sopenharmony_ci octeon_prepare_soft_command(oct, sc, OPCODE_NIC, 10238c2ecf20Sopenharmony_ci OPCODE_NIC_QCOUNT_UPDATE, 0, 10248c2ecf20Sopenharmony_ci if_cfg.u64, 0); 10258c2ecf20Sopenharmony_ci 10268c2ecf20Sopenharmony_ci init_completion(&sc->complete); 10278c2ecf20Sopenharmony_ci sc->sc_status = OCTEON_REQUEST_PENDING; 10288c2ecf20Sopenharmony_ci 10298c2ecf20Sopenharmony_ci retval = octeon_send_soft_command(oct, sc); 10308c2ecf20Sopenharmony_ci if (retval == IQ_SEND_FAILED) { 10318c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, 10328c2ecf20Sopenharmony_ci "Sending iq/oq config failed status: %x\n", 10338c2ecf20Sopenharmony_ci retval); 10348c2ecf20Sopenharmony_ci octeon_free_soft_command(oct, sc); 10358c2ecf20Sopenharmony_ci return -EIO; 10368c2ecf20Sopenharmony_ci } 10378c2ecf20Sopenharmony_ci 10388c2ecf20Sopenharmony_ci retval = wait_for_sc_completion_timeout(oct, sc, 0); 10398c2ecf20Sopenharmony_ci if (retval) 10408c2ecf20Sopenharmony_ci return retval; 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_ci retval = resp->status; 10438c2ecf20Sopenharmony_ci if (retval) { 10448c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, 10458c2ecf20Sopenharmony_ci "iq/oq config failed: %x\n", retval); 10468c2ecf20Sopenharmony_ci WRITE_ONCE(sc->caller_is_done, true); 10478c2ecf20Sopenharmony_ci return -1; 10488c2ecf20Sopenharmony_ci } 10498c2ecf20Sopenharmony_ci 10508c2ecf20Sopenharmony_ci octeon_swap_8B_data((u64 *)(&resp->cfg_info), 10518c2ecf20Sopenharmony_ci (sizeof(struct liquidio_if_cfg_info)) >> 3); 10528c2ecf20Sopenharmony_ci 10538c2ecf20Sopenharmony_ci lio->ifidx = ifidx_or_pfnum; 10548c2ecf20Sopenharmony_ci lio->linfo.num_rxpciq = hweight64(resp->cfg_info.iqmask); 10558c2ecf20Sopenharmony_ci lio->linfo.num_txpciq = hweight64(resp->cfg_info.iqmask); 10568c2ecf20Sopenharmony_ci for (j = 0; j < lio->linfo.num_rxpciq; j++) { 10578c2ecf20Sopenharmony_ci lio->linfo.rxpciq[j].u64 = 10588c2ecf20Sopenharmony_ci resp->cfg_info.linfo.rxpciq[j].u64; 10598c2ecf20Sopenharmony_ci } 10608c2ecf20Sopenharmony_ci 10618c2ecf20Sopenharmony_ci for (j = 0; j < lio->linfo.num_txpciq; j++) { 10628c2ecf20Sopenharmony_ci lio->linfo.txpciq[j].u64 = 10638c2ecf20Sopenharmony_ci resp->cfg_info.linfo.txpciq[j].u64; 10648c2ecf20Sopenharmony_ci } 10658c2ecf20Sopenharmony_ci 10668c2ecf20Sopenharmony_ci lio->linfo.hw_addr = resp->cfg_info.linfo.hw_addr; 10678c2ecf20Sopenharmony_ci lio->linfo.gmxport = resp->cfg_info.linfo.gmxport; 10688c2ecf20Sopenharmony_ci lio->linfo.link.u64 = resp->cfg_info.linfo.link.u64; 10698c2ecf20Sopenharmony_ci lio->txq = lio->linfo.txpciq[0].s.q_no; 10708c2ecf20Sopenharmony_ci lio->rxq = lio->linfo.rxpciq[0].s.q_no; 10718c2ecf20Sopenharmony_ci 10728c2ecf20Sopenharmony_ci dev_info(&oct->pci_dev->dev, "Queue count updated to %d\n", 10738c2ecf20Sopenharmony_ci lio->linfo.num_rxpciq); 10748c2ecf20Sopenharmony_ci 10758c2ecf20Sopenharmony_ci WRITE_ONCE(sc->caller_is_done, true); 10768c2ecf20Sopenharmony_ci 10778c2ecf20Sopenharmony_ci return 0; 10788c2ecf20Sopenharmony_ci} 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_cistatic int lio_reset_queues(struct net_device *netdev, uint32_t num_qs) 10818c2ecf20Sopenharmony_ci{ 10828c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 10838c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 10848c2ecf20Sopenharmony_ci int i, queue_count_update = 0; 10858c2ecf20Sopenharmony_ci struct napi_struct *napi, *n; 10868c2ecf20Sopenharmony_ci int ret; 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_ci schedule_timeout_uninterruptible(msecs_to_jiffies(100)); 10898c2ecf20Sopenharmony_ci 10908c2ecf20Sopenharmony_ci if (wait_for_pending_requests(oct)) 10918c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "There were pending requests\n"); 10928c2ecf20Sopenharmony_ci 10938c2ecf20Sopenharmony_ci if (lio_wait_for_instr_fetch(oct)) 10948c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "IQ had pending instructions\n"); 10958c2ecf20Sopenharmony_ci 10968c2ecf20Sopenharmony_ci if (octeon_set_io_queues_off(oct)) { 10978c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "Setting io queues off failed\n"); 10988c2ecf20Sopenharmony_ci return -1; 10998c2ecf20Sopenharmony_ci } 11008c2ecf20Sopenharmony_ci 11018c2ecf20Sopenharmony_ci /* Disable the input and output queues now. No more packets will 11028c2ecf20Sopenharmony_ci * arrive from Octeon. 11038c2ecf20Sopenharmony_ci */ 11048c2ecf20Sopenharmony_ci oct->fn_list.disable_io_queues(oct); 11058c2ecf20Sopenharmony_ci /* Delete NAPI */ 11068c2ecf20Sopenharmony_ci list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list) 11078c2ecf20Sopenharmony_ci netif_napi_del(napi); 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_ci if (num_qs != oct->num_iqs) { 11108c2ecf20Sopenharmony_ci ret = netif_set_real_num_rx_queues(netdev, num_qs); 11118c2ecf20Sopenharmony_ci if (ret) { 11128c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, 11138c2ecf20Sopenharmony_ci "Setting real number rx failed\n"); 11148c2ecf20Sopenharmony_ci return ret; 11158c2ecf20Sopenharmony_ci } 11168c2ecf20Sopenharmony_ci 11178c2ecf20Sopenharmony_ci ret = netif_set_real_num_tx_queues(netdev, num_qs); 11188c2ecf20Sopenharmony_ci if (ret) { 11198c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, 11208c2ecf20Sopenharmony_ci "Setting real number tx failed\n"); 11218c2ecf20Sopenharmony_ci return ret; 11228c2ecf20Sopenharmony_ci } 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_ci /* The value of queue_count_update decides whether it is the 11258c2ecf20Sopenharmony_ci * queue count or the descriptor count that is being 11268c2ecf20Sopenharmony_ci * re-configured. 11278c2ecf20Sopenharmony_ci */ 11288c2ecf20Sopenharmony_ci queue_count_update = 1; 11298c2ecf20Sopenharmony_ci } 11308c2ecf20Sopenharmony_ci 11318c2ecf20Sopenharmony_ci /* Re-configuration of queues can happen in two scenarios, SRIOV enabled 11328c2ecf20Sopenharmony_ci * and SRIOV disabled. Few things like recreating queue zero, resetting 11338c2ecf20Sopenharmony_ci * glists and IRQs are required for both. For the latter, some more 11348c2ecf20Sopenharmony_ci * steps like updating sriov_info for the octeon device need to be done. 11358c2ecf20Sopenharmony_ci */ 11368c2ecf20Sopenharmony_ci if (queue_count_update) { 11378c2ecf20Sopenharmony_ci cleanup_rx_oom_poll_fn(netdev); 11388c2ecf20Sopenharmony_ci 11398c2ecf20Sopenharmony_ci lio_delete_glists(lio); 11408c2ecf20Sopenharmony_ci 11418c2ecf20Sopenharmony_ci /* Delete mbox for PF which is SRIOV disabled because sriov_info 11428c2ecf20Sopenharmony_ci * will be now changed. 11438c2ecf20Sopenharmony_ci */ 11448c2ecf20Sopenharmony_ci if ((OCTEON_CN23XX_PF(oct)) && !oct->sriov_info.sriov_enabled) 11458c2ecf20Sopenharmony_ci oct->fn_list.free_mbox(oct); 11468c2ecf20Sopenharmony_ci } 11478c2ecf20Sopenharmony_ci 11488c2ecf20Sopenharmony_ci for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct); i++) { 11498c2ecf20Sopenharmony_ci if (!(oct->io_qmask.oq & BIT_ULL(i))) 11508c2ecf20Sopenharmony_ci continue; 11518c2ecf20Sopenharmony_ci octeon_delete_droq(oct, i); 11528c2ecf20Sopenharmony_ci } 11538c2ecf20Sopenharmony_ci 11548c2ecf20Sopenharmony_ci for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct); i++) { 11558c2ecf20Sopenharmony_ci if (!(oct->io_qmask.iq & BIT_ULL(i))) 11568c2ecf20Sopenharmony_ci continue; 11578c2ecf20Sopenharmony_ci octeon_delete_instr_queue(oct, i); 11588c2ecf20Sopenharmony_ci } 11598c2ecf20Sopenharmony_ci 11608c2ecf20Sopenharmony_ci if (queue_count_update) { 11618c2ecf20Sopenharmony_ci /* For PF re-configure sriov related information */ 11628c2ecf20Sopenharmony_ci if ((OCTEON_CN23XX_PF(oct)) && 11638c2ecf20Sopenharmony_ci !oct->sriov_info.sriov_enabled) { 11648c2ecf20Sopenharmony_ci oct->sriov_info.num_pf_rings = num_qs; 11658c2ecf20Sopenharmony_ci if (cn23xx_sriov_config(oct)) { 11668c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, 11678c2ecf20Sopenharmony_ci "Queue reset aborted: SRIOV config failed\n"); 11688c2ecf20Sopenharmony_ci return -1; 11698c2ecf20Sopenharmony_ci } 11708c2ecf20Sopenharmony_ci 11718c2ecf20Sopenharmony_ci num_qs = oct->sriov_info.num_pf_rings; 11728c2ecf20Sopenharmony_ci } 11738c2ecf20Sopenharmony_ci } 11748c2ecf20Sopenharmony_ci 11758c2ecf20Sopenharmony_ci if (oct->fn_list.setup_device_regs(oct)) { 11768c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "Failed to configure device registers\n"); 11778c2ecf20Sopenharmony_ci return -1; 11788c2ecf20Sopenharmony_ci } 11798c2ecf20Sopenharmony_ci 11808c2ecf20Sopenharmony_ci /* The following are needed in case of queue count re-configuration and 11818c2ecf20Sopenharmony_ci * not for descriptor count re-configuration. 11828c2ecf20Sopenharmony_ci */ 11838c2ecf20Sopenharmony_ci if (queue_count_update) { 11848c2ecf20Sopenharmony_ci if (octeon_setup_instr_queues(oct)) 11858c2ecf20Sopenharmony_ci return -1; 11868c2ecf20Sopenharmony_ci 11878c2ecf20Sopenharmony_ci if (octeon_setup_output_queues(oct)) 11888c2ecf20Sopenharmony_ci return -1; 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_ci /* Recreating mbox for PF that is SRIOV disabled */ 11918c2ecf20Sopenharmony_ci if (OCTEON_CN23XX_PF(oct) && !oct->sriov_info.sriov_enabled) { 11928c2ecf20Sopenharmony_ci if (oct->fn_list.setup_mbox(oct)) { 11938c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "Mailbox setup failed\n"); 11948c2ecf20Sopenharmony_ci return -1; 11958c2ecf20Sopenharmony_ci } 11968c2ecf20Sopenharmony_ci } 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_ci /* Deleting and recreating IRQs whether the interface is SRIOV 11998c2ecf20Sopenharmony_ci * enabled or disabled. 12008c2ecf20Sopenharmony_ci */ 12018c2ecf20Sopenharmony_ci if (lio_irq_reallocate_irqs(oct, num_qs)) { 12028c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "IRQs could not be allocated\n"); 12038c2ecf20Sopenharmony_ci return -1; 12048c2ecf20Sopenharmony_ci } 12058c2ecf20Sopenharmony_ci 12068c2ecf20Sopenharmony_ci /* Enable the input and output queues for this Octeon device */ 12078c2ecf20Sopenharmony_ci if (oct->fn_list.enable_io_queues(oct)) { 12088c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "Failed to enable input/output queues\n"); 12098c2ecf20Sopenharmony_ci return -1; 12108c2ecf20Sopenharmony_ci } 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci for (i = 0; i < oct->num_oqs; i++) 12138c2ecf20Sopenharmony_ci writel(oct->droq[i]->max_count, 12148c2ecf20Sopenharmony_ci oct->droq[i]->pkts_credit_reg); 12158c2ecf20Sopenharmony_ci 12168c2ecf20Sopenharmony_ci /* Informing firmware about the new queue count. It is required 12178c2ecf20Sopenharmony_ci * for firmware to allocate more number of queues than those at 12188c2ecf20Sopenharmony_ci * load time. 12198c2ecf20Sopenharmony_ci */ 12208c2ecf20Sopenharmony_ci if (OCTEON_CN23XX_PF(oct) && !oct->sriov_info.sriov_enabled) { 12218c2ecf20Sopenharmony_ci if (lio_23xx_reconfigure_queue_count(lio)) 12228c2ecf20Sopenharmony_ci return -1; 12238c2ecf20Sopenharmony_ci } 12248c2ecf20Sopenharmony_ci } 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_ci /* Once firmware is aware of the new value, queues can be recreated */ 12278c2ecf20Sopenharmony_ci if (liquidio_setup_io_queues(oct, 0, num_qs, num_qs)) { 12288c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "I/O queues creation failed\n"); 12298c2ecf20Sopenharmony_ci return -1; 12308c2ecf20Sopenharmony_ci } 12318c2ecf20Sopenharmony_ci 12328c2ecf20Sopenharmony_ci if (queue_count_update) { 12338c2ecf20Sopenharmony_ci if (lio_setup_glists(oct, lio, num_qs)) { 12348c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "Gather list allocation failed\n"); 12358c2ecf20Sopenharmony_ci return -1; 12368c2ecf20Sopenharmony_ci } 12378c2ecf20Sopenharmony_ci 12388c2ecf20Sopenharmony_ci if (setup_rx_oom_poll_fn(netdev)) { 12398c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "lio_setup_rx_oom_poll_fn failed\n"); 12408c2ecf20Sopenharmony_ci return 1; 12418c2ecf20Sopenharmony_ci } 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ci /* Send firmware the information about new number of queues 12448c2ecf20Sopenharmony_ci * if the interface is a VF or a PF that is SRIOV enabled. 12458c2ecf20Sopenharmony_ci */ 12468c2ecf20Sopenharmony_ci if (oct->sriov_info.sriov_enabled || OCTEON_CN23XX_VF(oct)) 12478c2ecf20Sopenharmony_ci if (lio_send_queue_count_update(netdev, num_qs)) 12488c2ecf20Sopenharmony_ci return -1; 12498c2ecf20Sopenharmony_ci } 12508c2ecf20Sopenharmony_ci 12518c2ecf20Sopenharmony_ci return 0; 12528c2ecf20Sopenharmony_ci} 12538c2ecf20Sopenharmony_ci 12548c2ecf20Sopenharmony_cistatic int lio_ethtool_set_ringparam(struct net_device *netdev, 12558c2ecf20Sopenharmony_ci struct ethtool_ringparam *ering) 12568c2ecf20Sopenharmony_ci{ 12578c2ecf20Sopenharmony_ci u32 rx_count, tx_count, rx_count_old, tx_count_old; 12588c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 12598c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 12608c2ecf20Sopenharmony_ci int stopped = 0; 12618c2ecf20Sopenharmony_ci 12628c2ecf20Sopenharmony_ci if (!OCTEON_CN23XX_PF(oct) && !OCTEON_CN23XX_VF(oct)) 12638c2ecf20Sopenharmony_ci return -EINVAL; 12648c2ecf20Sopenharmony_ci 12658c2ecf20Sopenharmony_ci if (ering->rx_mini_pending || ering->rx_jumbo_pending) 12668c2ecf20Sopenharmony_ci return -EINVAL; 12678c2ecf20Sopenharmony_ci 12688c2ecf20Sopenharmony_ci rx_count = clamp_t(u32, ering->rx_pending, CN23XX_MIN_OQ_DESCRIPTORS, 12698c2ecf20Sopenharmony_ci CN23XX_MAX_OQ_DESCRIPTORS); 12708c2ecf20Sopenharmony_ci tx_count = clamp_t(u32, ering->tx_pending, CN23XX_MIN_IQ_DESCRIPTORS, 12718c2ecf20Sopenharmony_ci CN23XX_MAX_IQ_DESCRIPTORS); 12728c2ecf20Sopenharmony_ci 12738c2ecf20Sopenharmony_ci rx_count_old = oct->droq[0]->max_count; 12748c2ecf20Sopenharmony_ci tx_count_old = oct->instr_queue[0]->max_count; 12758c2ecf20Sopenharmony_ci 12768c2ecf20Sopenharmony_ci if (rx_count == rx_count_old && tx_count == tx_count_old) 12778c2ecf20Sopenharmony_ci return 0; 12788c2ecf20Sopenharmony_ci 12798c2ecf20Sopenharmony_ci ifstate_set(lio, LIO_IFSTATE_RESETTING); 12808c2ecf20Sopenharmony_ci 12818c2ecf20Sopenharmony_ci if (netif_running(netdev)) { 12828c2ecf20Sopenharmony_ci netdev->netdev_ops->ndo_stop(netdev); 12838c2ecf20Sopenharmony_ci stopped = 1; 12848c2ecf20Sopenharmony_ci } 12858c2ecf20Sopenharmony_ci 12868c2ecf20Sopenharmony_ci /* Change RX/TX DESCS count */ 12878c2ecf20Sopenharmony_ci if (tx_count != tx_count_old) 12888c2ecf20Sopenharmony_ci CFG_SET_NUM_TX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx, 12898c2ecf20Sopenharmony_ci tx_count); 12908c2ecf20Sopenharmony_ci if (rx_count != rx_count_old) 12918c2ecf20Sopenharmony_ci CFG_SET_NUM_RX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx, 12928c2ecf20Sopenharmony_ci rx_count); 12938c2ecf20Sopenharmony_ci 12948c2ecf20Sopenharmony_ci if (lio_reset_queues(netdev, oct->num_iqs)) 12958c2ecf20Sopenharmony_ci goto err_lio_reset_queues; 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_ci if (stopped) 12988c2ecf20Sopenharmony_ci netdev->netdev_ops->ndo_open(netdev); 12998c2ecf20Sopenharmony_ci 13008c2ecf20Sopenharmony_ci ifstate_reset(lio, LIO_IFSTATE_RESETTING); 13018c2ecf20Sopenharmony_ci 13028c2ecf20Sopenharmony_ci return 0; 13038c2ecf20Sopenharmony_ci 13048c2ecf20Sopenharmony_cierr_lio_reset_queues: 13058c2ecf20Sopenharmony_ci if (tx_count != tx_count_old) 13068c2ecf20Sopenharmony_ci CFG_SET_NUM_TX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx, 13078c2ecf20Sopenharmony_ci tx_count_old); 13088c2ecf20Sopenharmony_ci if (rx_count != rx_count_old) 13098c2ecf20Sopenharmony_ci CFG_SET_NUM_RX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx, 13108c2ecf20Sopenharmony_ci rx_count_old); 13118c2ecf20Sopenharmony_ci return -EINVAL; 13128c2ecf20Sopenharmony_ci} 13138c2ecf20Sopenharmony_ci 13148c2ecf20Sopenharmony_cistatic u32 lio_get_msglevel(struct net_device *netdev) 13158c2ecf20Sopenharmony_ci{ 13168c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 13178c2ecf20Sopenharmony_ci 13188c2ecf20Sopenharmony_ci return lio->msg_enable; 13198c2ecf20Sopenharmony_ci} 13208c2ecf20Sopenharmony_ci 13218c2ecf20Sopenharmony_cistatic void lio_set_msglevel(struct net_device *netdev, u32 msglvl) 13228c2ecf20Sopenharmony_ci{ 13238c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 13248c2ecf20Sopenharmony_ci 13258c2ecf20Sopenharmony_ci if ((msglvl ^ lio->msg_enable) & NETIF_MSG_HW) { 13268c2ecf20Sopenharmony_ci if (msglvl & NETIF_MSG_HW) 13278c2ecf20Sopenharmony_ci liquidio_set_feature(netdev, 13288c2ecf20Sopenharmony_ci OCTNET_CMD_VERBOSE_ENABLE, 0); 13298c2ecf20Sopenharmony_ci else 13308c2ecf20Sopenharmony_ci liquidio_set_feature(netdev, 13318c2ecf20Sopenharmony_ci OCTNET_CMD_VERBOSE_DISABLE, 0); 13328c2ecf20Sopenharmony_ci } 13338c2ecf20Sopenharmony_ci 13348c2ecf20Sopenharmony_ci lio->msg_enable = msglvl; 13358c2ecf20Sopenharmony_ci} 13368c2ecf20Sopenharmony_ci 13378c2ecf20Sopenharmony_cistatic void lio_vf_set_msglevel(struct net_device *netdev, u32 msglvl) 13388c2ecf20Sopenharmony_ci{ 13398c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 13408c2ecf20Sopenharmony_ci 13418c2ecf20Sopenharmony_ci lio->msg_enable = msglvl; 13428c2ecf20Sopenharmony_ci} 13438c2ecf20Sopenharmony_ci 13448c2ecf20Sopenharmony_cistatic void 13458c2ecf20Sopenharmony_cilio_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) 13468c2ecf20Sopenharmony_ci{ 13478c2ecf20Sopenharmony_ci /* Notes: Not supporting any auto negotiation in these 13488c2ecf20Sopenharmony_ci * drivers. Just report pause frame support. 13498c2ecf20Sopenharmony_ci */ 13508c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 13518c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 13528c2ecf20Sopenharmony_ci 13538c2ecf20Sopenharmony_ci pause->autoneg = 0; 13548c2ecf20Sopenharmony_ci 13558c2ecf20Sopenharmony_ci pause->tx_pause = oct->tx_pause; 13568c2ecf20Sopenharmony_ci pause->rx_pause = oct->rx_pause; 13578c2ecf20Sopenharmony_ci} 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_cistatic int 13608c2ecf20Sopenharmony_cilio_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) 13618c2ecf20Sopenharmony_ci{ 13628c2ecf20Sopenharmony_ci /* Notes: Not supporting any auto negotiation in these 13638c2ecf20Sopenharmony_ci * drivers. 13648c2ecf20Sopenharmony_ci */ 13658c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 13668c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 13678c2ecf20Sopenharmony_ci struct octnic_ctrl_pkt nctrl; 13688c2ecf20Sopenharmony_ci struct oct_link_info *linfo = &lio->linfo; 13698c2ecf20Sopenharmony_ci 13708c2ecf20Sopenharmony_ci int ret = 0; 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci if (oct->chip_id != OCTEON_CN23XX_PF_VID) 13738c2ecf20Sopenharmony_ci return -EINVAL; 13748c2ecf20Sopenharmony_ci 13758c2ecf20Sopenharmony_ci if (linfo->link.s.duplex == 0) { 13768c2ecf20Sopenharmony_ci /*no flow control for half duplex*/ 13778c2ecf20Sopenharmony_ci if (pause->rx_pause || pause->tx_pause) 13788c2ecf20Sopenharmony_ci return -EINVAL; 13798c2ecf20Sopenharmony_ci } 13808c2ecf20Sopenharmony_ci 13818c2ecf20Sopenharmony_ci /*do not support autoneg of link flow control*/ 13828c2ecf20Sopenharmony_ci if (pause->autoneg == AUTONEG_ENABLE) 13838c2ecf20Sopenharmony_ci return -EINVAL; 13848c2ecf20Sopenharmony_ci 13858c2ecf20Sopenharmony_ci memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); 13868c2ecf20Sopenharmony_ci 13878c2ecf20Sopenharmony_ci nctrl.ncmd.u64 = 0; 13888c2ecf20Sopenharmony_ci nctrl.ncmd.s.cmd = OCTNET_CMD_SET_FLOW_CTL; 13898c2ecf20Sopenharmony_ci nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; 13908c2ecf20Sopenharmony_ci nctrl.netpndev = (u64)netdev; 13918c2ecf20Sopenharmony_ci nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_ci if (pause->rx_pause) { 13948c2ecf20Sopenharmony_ci /*enable rx pause*/ 13958c2ecf20Sopenharmony_ci nctrl.ncmd.s.param1 = 1; 13968c2ecf20Sopenharmony_ci } else { 13978c2ecf20Sopenharmony_ci /*disable rx pause*/ 13988c2ecf20Sopenharmony_ci nctrl.ncmd.s.param1 = 0; 13998c2ecf20Sopenharmony_ci } 14008c2ecf20Sopenharmony_ci 14018c2ecf20Sopenharmony_ci if (pause->tx_pause) { 14028c2ecf20Sopenharmony_ci /*enable tx pause*/ 14038c2ecf20Sopenharmony_ci nctrl.ncmd.s.param2 = 1; 14048c2ecf20Sopenharmony_ci } else { 14058c2ecf20Sopenharmony_ci /*disable tx pause*/ 14068c2ecf20Sopenharmony_ci nctrl.ncmd.s.param2 = 0; 14078c2ecf20Sopenharmony_ci } 14088c2ecf20Sopenharmony_ci 14098c2ecf20Sopenharmony_ci ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 14108c2ecf20Sopenharmony_ci if (ret) { 14118c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, 14128c2ecf20Sopenharmony_ci "Failed to set pause parameter, ret=%d\n", ret); 14138c2ecf20Sopenharmony_ci return -EINVAL; 14148c2ecf20Sopenharmony_ci } 14158c2ecf20Sopenharmony_ci 14168c2ecf20Sopenharmony_ci oct->rx_pause = pause->rx_pause; 14178c2ecf20Sopenharmony_ci oct->tx_pause = pause->tx_pause; 14188c2ecf20Sopenharmony_ci 14198c2ecf20Sopenharmony_ci return 0; 14208c2ecf20Sopenharmony_ci} 14218c2ecf20Sopenharmony_ci 14228c2ecf20Sopenharmony_cistatic void 14238c2ecf20Sopenharmony_cilio_get_ethtool_stats(struct net_device *netdev, 14248c2ecf20Sopenharmony_ci struct ethtool_stats *stats __attribute__((unused)), 14258c2ecf20Sopenharmony_ci u64 *data) 14268c2ecf20Sopenharmony_ci{ 14278c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 14288c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 14298c2ecf20Sopenharmony_ci struct rtnl_link_stats64 lstats; 14308c2ecf20Sopenharmony_ci int i = 0, j; 14318c2ecf20Sopenharmony_ci 14328c2ecf20Sopenharmony_ci if (ifstate_check(lio, LIO_IFSTATE_RESETTING)) 14338c2ecf20Sopenharmony_ci return; 14348c2ecf20Sopenharmony_ci 14358c2ecf20Sopenharmony_ci netdev->netdev_ops->ndo_get_stats64(netdev, &lstats); 14368c2ecf20Sopenharmony_ci /*sum of oct->droq[oq_no]->stats->rx_pkts_received */ 14378c2ecf20Sopenharmony_ci data[i++] = lstats.rx_packets; 14388c2ecf20Sopenharmony_ci /*sum of oct->instr_queue[iq_no]->stats.tx_done */ 14398c2ecf20Sopenharmony_ci data[i++] = lstats.tx_packets; 14408c2ecf20Sopenharmony_ci /*sum of oct->droq[oq_no]->stats->rx_bytes_received */ 14418c2ecf20Sopenharmony_ci data[i++] = lstats.rx_bytes; 14428c2ecf20Sopenharmony_ci /*sum of oct->instr_queue[iq_no]->stats.tx_tot_bytes */ 14438c2ecf20Sopenharmony_ci data[i++] = lstats.tx_bytes; 14448c2ecf20Sopenharmony_ci data[i++] = lstats.rx_errors + 14458c2ecf20Sopenharmony_ci oct_dev->link_stats.fromwire.fcs_err + 14468c2ecf20Sopenharmony_ci oct_dev->link_stats.fromwire.jabber_err + 14478c2ecf20Sopenharmony_ci oct_dev->link_stats.fromwire.l2_err + 14488c2ecf20Sopenharmony_ci oct_dev->link_stats.fromwire.frame_err; 14498c2ecf20Sopenharmony_ci data[i++] = lstats.tx_errors; 14508c2ecf20Sopenharmony_ci /*sum of oct->droq[oq_no]->stats->rx_dropped + 14518c2ecf20Sopenharmony_ci *oct->droq[oq_no]->stats->dropped_nodispatch + 14528c2ecf20Sopenharmony_ci *oct->droq[oq_no]->stats->dropped_toomany + 14538c2ecf20Sopenharmony_ci *oct->droq[oq_no]->stats->dropped_nomem 14548c2ecf20Sopenharmony_ci */ 14558c2ecf20Sopenharmony_ci data[i++] = lstats.rx_dropped + 14568c2ecf20Sopenharmony_ci oct_dev->link_stats.fromwire.fifo_err + 14578c2ecf20Sopenharmony_ci oct_dev->link_stats.fromwire.dmac_drop + 14588c2ecf20Sopenharmony_ci oct_dev->link_stats.fromwire.red_drops + 14598c2ecf20Sopenharmony_ci oct_dev->link_stats.fromwire.fw_err_pko + 14608c2ecf20Sopenharmony_ci oct_dev->link_stats.fromwire.fw_err_link + 14618c2ecf20Sopenharmony_ci oct_dev->link_stats.fromwire.fw_err_drop; 14628c2ecf20Sopenharmony_ci /*sum of oct->instr_queue[iq_no]->stats.tx_dropped */ 14638c2ecf20Sopenharmony_ci data[i++] = lstats.tx_dropped + 14648c2ecf20Sopenharmony_ci oct_dev->link_stats.fromhost.max_collision_fail + 14658c2ecf20Sopenharmony_ci oct_dev->link_stats.fromhost.max_deferral_fail + 14668c2ecf20Sopenharmony_ci oct_dev->link_stats.fromhost.total_collisions + 14678c2ecf20Sopenharmony_ci oct_dev->link_stats.fromhost.fw_err_pko + 14688c2ecf20Sopenharmony_ci oct_dev->link_stats.fromhost.fw_err_link + 14698c2ecf20Sopenharmony_ci oct_dev->link_stats.fromhost.fw_err_drop + 14708c2ecf20Sopenharmony_ci oct_dev->link_stats.fromhost.fw_err_pki; 14718c2ecf20Sopenharmony_ci 14728c2ecf20Sopenharmony_ci /* firmware tx stats */ 14738c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[mdata->from_ifidx]. 14748c2ecf20Sopenharmony_ci *fromhost.fw_total_sent 14758c2ecf20Sopenharmony_ci */ 14768c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_total_sent); 14778c2ecf20Sopenharmony_ci /*per_core_stats[i].link_stats[port].fromwire.fw_total_fwd */ 14788c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_total_fwd); 14798c2ecf20Sopenharmony_ci /*per_core_stats[j].link_stats[i].fromhost.fw_err_pko */ 14808c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_pko); 14818c2ecf20Sopenharmony_ci /*per_core_stats[j].link_stats[i].fromhost.fw_err_pki */ 14828c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_pki); 14838c2ecf20Sopenharmony_ci /*per_core_stats[j].link_stats[i].fromhost.fw_err_link */ 14848c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_link); 14858c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost. 14868c2ecf20Sopenharmony_ci *fw_err_drop 14878c2ecf20Sopenharmony_ci */ 14888c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_drop); 14898c2ecf20Sopenharmony_ci 14908c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.fw_tso */ 14918c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tso); 14928c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost. 14938c2ecf20Sopenharmony_ci *fw_tso_fwd 14948c2ecf20Sopenharmony_ci */ 14958c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tso_fwd); 14968c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost. 14978c2ecf20Sopenharmony_ci *fw_err_tso 14988c2ecf20Sopenharmony_ci */ 14998c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_tso); 15008c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost. 15018c2ecf20Sopenharmony_ci *fw_tx_vxlan 15028c2ecf20Sopenharmony_ci */ 15038c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tx_vxlan); 15048c2ecf20Sopenharmony_ci 15058c2ecf20Sopenharmony_ci /* Multicast packets sent by this port */ 15068c2ecf20Sopenharmony_ci data[i++] = oct_dev->link_stats.fromhost.fw_total_mcast_sent; 15078c2ecf20Sopenharmony_ci data[i++] = oct_dev->link_stats.fromhost.fw_total_bcast_sent; 15088c2ecf20Sopenharmony_ci 15098c2ecf20Sopenharmony_ci /* mac tx statistics */ 15108c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT5 */ 15118c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_pkts_sent); 15128c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT4 */ 15138c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_bytes_sent); 15148c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT15 */ 15158c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.mcast_pkts_sent); 15168c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT14 */ 15178c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.bcast_pkts_sent); 15188c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT17 */ 15198c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.ctl_sent); 15208c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT0 */ 15218c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_collisions); 15228c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT3 */ 15238c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.one_collision_sent); 15248c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT2 */ 15258c2ecf20Sopenharmony_ci data[i++] = 15268c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->link_stats.fromhost.multi_collision_sent); 15278c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT0 */ 15288c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.max_collision_fail); 15298c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT1 */ 15308c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.max_deferral_fail); 15318c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT16 */ 15328c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fifo_err); 15338c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_TX_STAT6 */ 15348c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.runts); 15358c2ecf20Sopenharmony_ci 15368c2ecf20Sopenharmony_ci /* RX firmware stats */ 15378c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. 15388c2ecf20Sopenharmony_ci *fw_total_rcvd 15398c2ecf20Sopenharmony_ci */ 15408c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_rcvd); 15418c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. 15428c2ecf20Sopenharmony_ci *fw_total_fwd 15438c2ecf20Sopenharmony_ci */ 15448c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_fwd); 15458c2ecf20Sopenharmony_ci /* Multicast packets received on this port */ 15468c2ecf20Sopenharmony_ci data[i++] = oct_dev->link_stats.fromwire.fw_total_mcast; 15478c2ecf20Sopenharmony_ci data[i++] = oct_dev->link_stats.fromwire.fw_total_bcast; 15488c2ecf20Sopenharmony_ci /*per_core_stats[core_id].link_stats[ifidx].fromwire.jabber_err */ 15498c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.jabber_err); 15508c2ecf20Sopenharmony_ci /*per_core_stats[core_id].link_stats[ifidx].fromwire.l2_err */ 15518c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.l2_err); 15528c2ecf20Sopenharmony_ci /*per_core_stats[core_id].link_stats[ifidx].fromwire.frame_err */ 15538c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.frame_err); 15548c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. 15558c2ecf20Sopenharmony_ci *fw_err_pko 15568c2ecf20Sopenharmony_ci */ 15578c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_pko); 15588c2ecf20Sopenharmony_ci /*per_core_stats[j].link_stats[i].fromwire.fw_err_link */ 15598c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_link); 15608c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx]. 15618c2ecf20Sopenharmony_ci *fromwire.fw_err_drop 15628c2ecf20Sopenharmony_ci */ 15638c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_drop); 15648c2ecf20Sopenharmony_ci 15658c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx]. 15668c2ecf20Sopenharmony_ci *fromwire.fw_rx_vxlan 15678c2ecf20Sopenharmony_ci */ 15688c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_rx_vxlan); 15698c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx]. 15708c2ecf20Sopenharmony_ci *fromwire.fw_rx_vxlan_err 15718c2ecf20Sopenharmony_ci */ 15728c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_rx_vxlan_err); 15738c2ecf20Sopenharmony_ci 15748c2ecf20Sopenharmony_ci /* LRO */ 15758c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. 15768c2ecf20Sopenharmony_ci *fw_lro_pkts 15778c2ecf20Sopenharmony_ci */ 15788c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_pkts); 15798c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. 15808c2ecf20Sopenharmony_ci *fw_lro_octs 15818c2ecf20Sopenharmony_ci */ 15828c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_octs); 15838c2ecf20Sopenharmony_ci /*per_core_stats[j].link_stats[i].fromwire.fw_total_lro */ 15848c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_lro); 15858c2ecf20Sopenharmony_ci /*per_core_stats[j].link_stats[i].fromwire.fw_lro_aborts */ 15868c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts); 15878c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. 15888c2ecf20Sopenharmony_ci *fw_lro_aborts_port 15898c2ecf20Sopenharmony_ci */ 15908c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_port); 15918c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. 15928c2ecf20Sopenharmony_ci *fw_lro_aborts_seq 15938c2ecf20Sopenharmony_ci */ 15948c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_seq); 15958c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. 15968c2ecf20Sopenharmony_ci *fw_lro_aborts_tsval 15978c2ecf20Sopenharmony_ci */ 15988c2ecf20Sopenharmony_ci data[i++] = 15998c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_tsval); 16008c2ecf20Sopenharmony_ci /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. 16018c2ecf20Sopenharmony_ci *fw_lro_aborts_timer 16028c2ecf20Sopenharmony_ci */ 16038c2ecf20Sopenharmony_ci /* intrmod: packet forward rate */ 16048c2ecf20Sopenharmony_ci data[i++] = 16058c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_timer); 16068c2ecf20Sopenharmony_ci /*per_core_stats[j].link_stats[i].fromwire.fw_lro_aborts */ 16078c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fwd_rate); 16088c2ecf20Sopenharmony_ci 16098c2ecf20Sopenharmony_ci /* mac: link-level stats */ 16108c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_RX_STAT0 */ 16118c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_rcvd); 16128c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_RX_STAT1 */ 16138c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.bytes_rcvd); 16148c2ecf20Sopenharmony_ci /*CVMX_PKI_STATX_STAT5 */ 16158c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_bcst); 16168c2ecf20Sopenharmony_ci /*CVMX_PKI_STATX_STAT5 */ 16178c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_mcst); 16188c2ecf20Sopenharmony_ci /*wqe->word2.err_code or wqe->word2.err_level */ 16198c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.runts); 16208c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_RX_STAT2 */ 16218c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.ctl_rcvd); 16228c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_RX_STAT6 */ 16238c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fifo_err); 16248c2ecf20Sopenharmony_ci /*CVMX_BGXX_CMRX_RX_STAT4 */ 16258c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.dmac_drop); 16268c2ecf20Sopenharmony_ci /*wqe->word2.err_code or wqe->word2.err_level */ 16278c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fcs_err); 16288c2ecf20Sopenharmony_ci /*lio->link_changes*/ 16298c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(lio->link_changes); 16308c2ecf20Sopenharmony_ci 16318c2ecf20Sopenharmony_ci for (j = 0; j < MAX_OCTEON_INSTR_QUEUES(oct_dev); j++) { 16328c2ecf20Sopenharmony_ci if (!(oct_dev->io_qmask.iq & BIT_ULL(j))) 16338c2ecf20Sopenharmony_ci continue; 16348c2ecf20Sopenharmony_ci /*packets to network port*/ 16358c2ecf20Sopenharmony_ci /*# of packets tx to network */ 16368c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_done); 16378c2ecf20Sopenharmony_ci /*# of bytes tx to network */ 16388c2ecf20Sopenharmony_ci data[i++] = 16398c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_tot_bytes); 16408c2ecf20Sopenharmony_ci /*# of packets dropped */ 16418c2ecf20Sopenharmony_ci data[i++] = 16428c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_dropped); 16438c2ecf20Sopenharmony_ci /*# of tx fails due to queue full */ 16448c2ecf20Sopenharmony_ci data[i++] = 16458c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_iq_busy); 16468c2ecf20Sopenharmony_ci /*XXX gather entries sent */ 16478c2ecf20Sopenharmony_ci data[i++] = 16488c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->instr_queue[j]->stats.sgentry_sent); 16498c2ecf20Sopenharmony_ci 16508c2ecf20Sopenharmony_ci /*instruction to firmware: data and control */ 16518c2ecf20Sopenharmony_ci /*# of instructions to the queue */ 16528c2ecf20Sopenharmony_ci data[i++] = 16538c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_posted); 16548c2ecf20Sopenharmony_ci /*# of instructions processed */ 16558c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 16568c2ecf20Sopenharmony_ci oct_dev->instr_queue[j]->stats.instr_processed); 16578c2ecf20Sopenharmony_ci /*# of instructions could not be processed */ 16588c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 16598c2ecf20Sopenharmony_ci oct_dev->instr_queue[j]->stats.instr_dropped); 16608c2ecf20Sopenharmony_ci /*bytes sent through the queue */ 16618c2ecf20Sopenharmony_ci data[i++] = 16628c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->instr_queue[j]->stats.bytes_sent); 16638c2ecf20Sopenharmony_ci 16648c2ecf20Sopenharmony_ci /*tso request*/ 16658c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_gso); 16668c2ecf20Sopenharmony_ci /*vxlan request*/ 16678c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_vxlan); 16688c2ecf20Sopenharmony_ci /*txq restart*/ 16698c2ecf20Sopenharmony_ci data[i++] = 16708c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_restart); 16718c2ecf20Sopenharmony_ci } 16728c2ecf20Sopenharmony_ci 16738c2ecf20Sopenharmony_ci /* RX */ 16748c2ecf20Sopenharmony_ci for (j = 0; j < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); j++) { 16758c2ecf20Sopenharmony_ci if (!(oct_dev->io_qmask.oq & BIT_ULL(j))) 16768c2ecf20Sopenharmony_ci continue; 16778c2ecf20Sopenharmony_ci 16788c2ecf20Sopenharmony_ci /*packets send to TCP/IP network stack */ 16798c2ecf20Sopenharmony_ci /*# of packets to network stack */ 16808c2ecf20Sopenharmony_ci data[i++] = 16818c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.rx_pkts_received); 16828c2ecf20Sopenharmony_ci /*# of bytes to network stack */ 16838c2ecf20Sopenharmony_ci data[i++] = 16848c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.rx_bytes_received); 16858c2ecf20Sopenharmony_ci /*# of packets dropped */ 16868c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem + 16878c2ecf20Sopenharmony_ci oct_dev->droq[j]->stats.dropped_toomany + 16888c2ecf20Sopenharmony_ci oct_dev->droq[j]->stats.rx_dropped); 16898c2ecf20Sopenharmony_ci data[i++] = 16908c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem); 16918c2ecf20Sopenharmony_ci data[i++] = 16928c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.dropped_toomany); 16938c2ecf20Sopenharmony_ci data[i++] = 16948c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.rx_dropped); 16958c2ecf20Sopenharmony_ci 16968c2ecf20Sopenharmony_ci /*control and data path*/ 16978c2ecf20Sopenharmony_ci data[i++] = 16988c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.pkts_received); 16998c2ecf20Sopenharmony_ci data[i++] = 17008c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.bytes_received); 17018c2ecf20Sopenharmony_ci data[i++] = 17028c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.dropped_nodispatch); 17038c2ecf20Sopenharmony_ci 17048c2ecf20Sopenharmony_ci data[i++] = 17058c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.rx_vxlan); 17068c2ecf20Sopenharmony_ci data[i++] = 17078c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.rx_alloc_failure); 17088c2ecf20Sopenharmony_ci } 17098c2ecf20Sopenharmony_ci} 17108c2ecf20Sopenharmony_ci 17118c2ecf20Sopenharmony_cistatic void lio_vf_get_ethtool_stats(struct net_device *netdev, 17128c2ecf20Sopenharmony_ci struct ethtool_stats *stats 17138c2ecf20Sopenharmony_ci __attribute__((unused)), 17148c2ecf20Sopenharmony_ci u64 *data) 17158c2ecf20Sopenharmony_ci{ 17168c2ecf20Sopenharmony_ci struct rtnl_link_stats64 lstats; 17178c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 17188c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 17198c2ecf20Sopenharmony_ci int i = 0, j, vj; 17208c2ecf20Sopenharmony_ci 17218c2ecf20Sopenharmony_ci if (ifstate_check(lio, LIO_IFSTATE_RESETTING)) 17228c2ecf20Sopenharmony_ci return; 17238c2ecf20Sopenharmony_ci 17248c2ecf20Sopenharmony_ci netdev->netdev_ops->ndo_get_stats64(netdev, &lstats); 17258c2ecf20Sopenharmony_ci /* sum of oct->droq[oq_no]->stats->rx_pkts_received */ 17268c2ecf20Sopenharmony_ci data[i++] = lstats.rx_packets; 17278c2ecf20Sopenharmony_ci /* sum of oct->instr_queue[iq_no]->stats.tx_done */ 17288c2ecf20Sopenharmony_ci data[i++] = lstats.tx_packets; 17298c2ecf20Sopenharmony_ci /* sum of oct->droq[oq_no]->stats->rx_bytes_received */ 17308c2ecf20Sopenharmony_ci data[i++] = lstats.rx_bytes; 17318c2ecf20Sopenharmony_ci /* sum of oct->instr_queue[iq_no]->stats.tx_tot_bytes */ 17328c2ecf20Sopenharmony_ci data[i++] = lstats.tx_bytes; 17338c2ecf20Sopenharmony_ci data[i++] = lstats.rx_errors; 17348c2ecf20Sopenharmony_ci data[i++] = lstats.tx_errors; 17358c2ecf20Sopenharmony_ci /* sum of oct->droq[oq_no]->stats->rx_dropped + 17368c2ecf20Sopenharmony_ci * oct->droq[oq_no]->stats->dropped_nodispatch + 17378c2ecf20Sopenharmony_ci * oct->droq[oq_no]->stats->dropped_toomany + 17388c2ecf20Sopenharmony_ci * oct->droq[oq_no]->stats->dropped_nomem 17398c2ecf20Sopenharmony_ci */ 17408c2ecf20Sopenharmony_ci data[i++] = lstats.rx_dropped; 17418c2ecf20Sopenharmony_ci /* sum of oct->instr_queue[iq_no]->stats.tx_dropped */ 17428c2ecf20Sopenharmony_ci data[i++] = lstats.tx_dropped + 17438c2ecf20Sopenharmony_ci oct_dev->link_stats.fromhost.fw_err_drop; 17448c2ecf20Sopenharmony_ci 17458c2ecf20Sopenharmony_ci data[i++] = oct_dev->link_stats.fromwire.fw_total_mcast; 17468c2ecf20Sopenharmony_ci data[i++] = oct_dev->link_stats.fromhost.fw_total_mcast_sent; 17478c2ecf20Sopenharmony_ci data[i++] = oct_dev->link_stats.fromwire.fw_total_bcast; 17488c2ecf20Sopenharmony_ci data[i++] = oct_dev->link_stats.fromhost.fw_total_bcast_sent; 17498c2ecf20Sopenharmony_ci 17508c2ecf20Sopenharmony_ci /* lio->link_changes */ 17518c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(lio->link_changes); 17528c2ecf20Sopenharmony_ci 17538c2ecf20Sopenharmony_ci for (vj = 0; vj < oct_dev->num_iqs; vj++) { 17548c2ecf20Sopenharmony_ci j = lio->linfo.txpciq[vj].s.q_no; 17558c2ecf20Sopenharmony_ci 17568c2ecf20Sopenharmony_ci /* packets to network port */ 17578c2ecf20Sopenharmony_ci /* # of packets tx to network */ 17588c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_done); 17598c2ecf20Sopenharmony_ci /* # of bytes tx to network */ 17608c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 17618c2ecf20Sopenharmony_ci oct_dev->instr_queue[j]->stats.tx_tot_bytes); 17628c2ecf20Sopenharmony_ci /* # of packets dropped */ 17638c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 17648c2ecf20Sopenharmony_ci oct_dev->instr_queue[j]->stats.tx_dropped); 17658c2ecf20Sopenharmony_ci /* # of tx fails due to queue full */ 17668c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 17678c2ecf20Sopenharmony_ci oct_dev->instr_queue[j]->stats.tx_iq_busy); 17688c2ecf20Sopenharmony_ci /* XXX gather entries sent */ 17698c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 17708c2ecf20Sopenharmony_ci oct_dev->instr_queue[j]->stats.sgentry_sent); 17718c2ecf20Sopenharmony_ci 17728c2ecf20Sopenharmony_ci /* instruction to firmware: data and control */ 17738c2ecf20Sopenharmony_ci /* # of instructions to the queue */ 17748c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 17758c2ecf20Sopenharmony_ci oct_dev->instr_queue[j]->stats.instr_posted); 17768c2ecf20Sopenharmony_ci /* # of instructions processed */ 17778c2ecf20Sopenharmony_ci data[i++] = 17788c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_processed); 17798c2ecf20Sopenharmony_ci /* # of instructions could not be processed */ 17808c2ecf20Sopenharmony_ci data[i++] = 17818c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_dropped); 17828c2ecf20Sopenharmony_ci /* bytes sent through the queue */ 17838c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 17848c2ecf20Sopenharmony_ci oct_dev->instr_queue[j]->stats.bytes_sent); 17858c2ecf20Sopenharmony_ci /* tso request */ 17868c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_gso); 17878c2ecf20Sopenharmony_ci /* vxlan request */ 17888c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_vxlan); 17898c2ecf20Sopenharmony_ci /* txq restart */ 17908c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 17918c2ecf20Sopenharmony_ci oct_dev->instr_queue[j]->stats.tx_restart); 17928c2ecf20Sopenharmony_ci } 17938c2ecf20Sopenharmony_ci 17948c2ecf20Sopenharmony_ci /* RX */ 17958c2ecf20Sopenharmony_ci for (vj = 0; vj < oct_dev->num_oqs; vj++) { 17968c2ecf20Sopenharmony_ci j = lio->linfo.rxpciq[vj].s.q_no; 17978c2ecf20Sopenharmony_ci 17988c2ecf20Sopenharmony_ci /* packets send to TCP/IP network stack */ 17998c2ecf20Sopenharmony_ci /* # of packets to network stack */ 18008c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 18018c2ecf20Sopenharmony_ci oct_dev->droq[j]->stats.rx_pkts_received); 18028c2ecf20Sopenharmony_ci /* # of bytes to network stack */ 18038c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64( 18048c2ecf20Sopenharmony_ci oct_dev->droq[j]->stats.rx_bytes_received); 18058c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem + 18068c2ecf20Sopenharmony_ci oct_dev->droq[j]->stats.dropped_toomany + 18078c2ecf20Sopenharmony_ci oct_dev->droq[j]->stats.rx_dropped); 18088c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem); 18098c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_toomany); 18108c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.rx_dropped); 18118c2ecf20Sopenharmony_ci 18128c2ecf20Sopenharmony_ci /* control and data path */ 18138c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.pkts_received); 18148c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.bytes_received); 18158c2ecf20Sopenharmony_ci data[i++] = 18168c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.dropped_nodispatch); 18178c2ecf20Sopenharmony_ci 18188c2ecf20Sopenharmony_ci data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.rx_vxlan); 18198c2ecf20Sopenharmony_ci data[i++] = 18208c2ecf20Sopenharmony_ci CVM_CAST64(oct_dev->droq[j]->stats.rx_alloc_failure); 18218c2ecf20Sopenharmony_ci } 18228c2ecf20Sopenharmony_ci} 18238c2ecf20Sopenharmony_ci 18248c2ecf20Sopenharmony_cistatic void lio_get_priv_flags_strings(struct lio *lio, u8 *data) 18258c2ecf20Sopenharmony_ci{ 18268c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 18278c2ecf20Sopenharmony_ci int i; 18288c2ecf20Sopenharmony_ci 18298c2ecf20Sopenharmony_ci switch (oct_dev->chip_id) { 18308c2ecf20Sopenharmony_ci case OCTEON_CN23XX_PF_VID: 18318c2ecf20Sopenharmony_ci case OCTEON_CN23XX_VF_VID: 18328c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(oct_priv_flags_strings); i++) { 18338c2ecf20Sopenharmony_ci sprintf(data, "%s", oct_priv_flags_strings[i]); 18348c2ecf20Sopenharmony_ci data += ETH_GSTRING_LEN; 18358c2ecf20Sopenharmony_ci } 18368c2ecf20Sopenharmony_ci break; 18378c2ecf20Sopenharmony_ci case OCTEON_CN68XX: 18388c2ecf20Sopenharmony_ci case OCTEON_CN66XX: 18398c2ecf20Sopenharmony_ci break; 18408c2ecf20Sopenharmony_ci default: 18418c2ecf20Sopenharmony_ci netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n"); 18428c2ecf20Sopenharmony_ci break; 18438c2ecf20Sopenharmony_ci } 18448c2ecf20Sopenharmony_ci} 18458c2ecf20Sopenharmony_ci 18468c2ecf20Sopenharmony_cistatic void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data) 18478c2ecf20Sopenharmony_ci{ 18488c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 18498c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 18508c2ecf20Sopenharmony_ci int num_iq_stats, num_oq_stats, i, j; 18518c2ecf20Sopenharmony_ci int num_stats; 18528c2ecf20Sopenharmony_ci 18538c2ecf20Sopenharmony_ci switch (stringset) { 18548c2ecf20Sopenharmony_ci case ETH_SS_STATS: 18558c2ecf20Sopenharmony_ci num_stats = ARRAY_SIZE(oct_stats_strings); 18568c2ecf20Sopenharmony_ci for (j = 0; j < num_stats; j++) { 18578c2ecf20Sopenharmony_ci sprintf(data, "%s", oct_stats_strings[j]); 18588c2ecf20Sopenharmony_ci data += ETH_GSTRING_LEN; 18598c2ecf20Sopenharmony_ci } 18608c2ecf20Sopenharmony_ci 18618c2ecf20Sopenharmony_ci num_iq_stats = ARRAY_SIZE(oct_iq_stats_strings); 18628c2ecf20Sopenharmony_ci for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct_dev); i++) { 18638c2ecf20Sopenharmony_ci if (!(oct_dev->io_qmask.iq & BIT_ULL(i))) 18648c2ecf20Sopenharmony_ci continue; 18658c2ecf20Sopenharmony_ci for (j = 0; j < num_iq_stats; j++) { 18668c2ecf20Sopenharmony_ci sprintf(data, "tx-%d-%s", i, 18678c2ecf20Sopenharmony_ci oct_iq_stats_strings[j]); 18688c2ecf20Sopenharmony_ci data += ETH_GSTRING_LEN; 18698c2ecf20Sopenharmony_ci } 18708c2ecf20Sopenharmony_ci } 18718c2ecf20Sopenharmony_ci 18728c2ecf20Sopenharmony_ci num_oq_stats = ARRAY_SIZE(oct_droq_stats_strings); 18738c2ecf20Sopenharmony_ci for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); i++) { 18748c2ecf20Sopenharmony_ci if (!(oct_dev->io_qmask.oq & BIT_ULL(i))) 18758c2ecf20Sopenharmony_ci continue; 18768c2ecf20Sopenharmony_ci for (j = 0; j < num_oq_stats; j++) { 18778c2ecf20Sopenharmony_ci sprintf(data, "rx-%d-%s", i, 18788c2ecf20Sopenharmony_ci oct_droq_stats_strings[j]); 18798c2ecf20Sopenharmony_ci data += ETH_GSTRING_LEN; 18808c2ecf20Sopenharmony_ci } 18818c2ecf20Sopenharmony_ci } 18828c2ecf20Sopenharmony_ci break; 18838c2ecf20Sopenharmony_ci 18848c2ecf20Sopenharmony_ci case ETH_SS_PRIV_FLAGS: 18858c2ecf20Sopenharmony_ci lio_get_priv_flags_strings(lio, data); 18868c2ecf20Sopenharmony_ci break; 18878c2ecf20Sopenharmony_ci default: 18888c2ecf20Sopenharmony_ci netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n"); 18898c2ecf20Sopenharmony_ci break; 18908c2ecf20Sopenharmony_ci } 18918c2ecf20Sopenharmony_ci} 18928c2ecf20Sopenharmony_ci 18938c2ecf20Sopenharmony_cistatic void lio_vf_get_strings(struct net_device *netdev, u32 stringset, 18948c2ecf20Sopenharmony_ci u8 *data) 18958c2ecf20Sopenharmony_ci{ 18968c2ecf20Sopenharmony_ci int num_iq_stats, num_oq_stats, i, j; 18978c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 18988c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 18998c2ecf20Sopenharmony_ci int num_stats; 19008c2ecf20Sopenharmony_ci 19018c2ecf20Sopenharmony_ci switch (stringset) { 19028c2ecf20Sopenharmony_ci case ETH_SS_STATS: 19038c2ecf20Sopenharmony_ci num_stats = ARRAY_SIZE(oct_vf_stats_strings); 19048c2ecf20Sopenharmony_ci for (j = 0; j < num_stats; j++) { 19058c2ecf20Sopenharmony_ci sprintf(data, "%s", oct_vf_stats_strings[j]); 19068c2ecf20Sopenharmony_ci data += ETH_GSTRING_LEN; 19078c2ecf20Sopenharmony_ci } 19088c2ecf20Sopenharmony_ci 19098c2ecf20Sopenharmony_ci num_iq_stats = ARRAY_SIZE(oct_iq_stats_strings); 19108c2ecf20Sopenharmony_ci for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct_dev); i++) { 19118c2ecf20Sopenharmony_ci if (!(oct_dev->io_qmask.iq & BIT_ULL(i))) 19128c2ecf20Sopenharmony_ci continue; 19138c2ecf20Sopenharmony_ci for (j = 0; j < num_iq_stats; j++) { 19148c2ecf20Sopenharmony_ci sprintf(data, "tx-%d-%s", i, 19158c2ecf20Sopenharmony_ci oct_iq_stats_strings[j]); 19168c2ecf20Sopenharmony_ci data += ETH_GSTRING_LEN; 19178c2ecf20Sopenharmony_ci } 19188c2ecf20Sopenharmony_ci } 19198c2ecf20Sopenharmony_ci 19208c2ecf20Sopenharmony_ci num_oq_stats = ARRAY_SIZE(oct_droq_stats_strings); 19218c2ecf20Sopenharmony_ci for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); i++) { 19228c2ecf20Sopenharmony_ci if (!(oct_dev->io_qmask.oq & BIT_ULL(i))) 19238c2ecf20Sopenharmony_ci continue; 19248c2ecf20Sopenharmony_ci for (j = 0; j < num_oq_stats; j++) { 19258c2ecf20Sopenharmony_ci sprintf(data, "rx-%d-%s", i, 19268c2ecf20Sopenharmony_ci oct_droq_stats_strings[j]); 19278c2ecf20Sopenharmony_ci data += ETH_GSTRING_LEN; 19288c2ecf20Sopenharmony_ci } 19298c2ecf20Sopenharmony_ci } 19308c2ecf20Sopenharmony_ci break; 19318c2ecf20Sopenharmony_ci 19328c2ecf20Sopenharmony_ci case ETH_SS_PRIV_FLAGS: 19338c2ecf20Sopenharmony_ci lio_get_priv_flags_strings(lio, data); 19348c2ecf20Sopenharmony_ci break; 19358c2ecf20Sopenharmony_ci default: 19368c2ecf20Sopenharmony_ci netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n"); 19378c2ecf20Sopenharmony_ci break; 19388c2ecf20Sopenharmony_ci } 19398c2ecf20Sopenharmony_ci} 19408c2ecf20Sopenharmony_ci 19418c2ecf20Sopenharmony_cistatic int lio_get_priv_flags_ss_count(struct lio *lio) 19428c2ecf20Sopenharmony_ci{ 19438c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 19448c2ecf20Sopenharmony_ci 19458c2ecf20Sopenharmony_ci switch (oct_dev->chip_id) { 19468c2ecf20Sopenharmony_ci case OCTEON_CN23XX_PF_VID: 19478c2ecf20Sopenharmony_ci case OCTEON_CN23XX_VF_VID: 19488c2ecf20Sopenharmony_ci return ARRAY_SIZE(oct_priv_flags_strings); 19498c2ecf20Sopenharmony_ci case OCTEON_CN68XX: 19508c2ecf20Sopenharmony_ci case OCTEON_CN66XX: 19518c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 19528c2ecf20Sopenharmony_ci default: 19538c2ecf20Sopenharmony_ci netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n"); 19548c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 19558c2ecf20Sopenharmony_ci } 19568c2ecf20Sopenharmony_ci} 19578c2ecf20Sopenharmony_ci 19588c2ecf20Sopenharmony_cistatic int lio_get_sset_count(struct net_device *netdev, int sset) 19598c2ecf20Sopenharmony_ci{ 19608c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 19618c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 19628c2ecf20Sopenharmony_ci 19638c2ecf20Sopenharmony_ci switch (sset) { 19648c2ecf20Sopenharmony_ci case ETH_SS_STATS: 19658c2ecf20Sopenharmony_ci return (ARRAY_SIZE(oct_stats_strings) + 19668c2ecf20Sopenharmony_ci ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs + 19678c2ecf20Sopenharmony_ci ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs); 19688c2ecf20Sopenharmony_ci case ETH_SS_PRIV_FLAGS: 19698c2ecf20Sopenharmony_ci return lio_get_priv_flags_ss_count(lio); 19708c2ecf20Sopenharmony_ci default: 19718c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 19728c2ecf20Sopenharmony_ci } 19738c2ecf20Sopenharmony_ci} 19748c2ecf20Sopenharmony_ci 19758c2ecf20Sopenharmony_cistatic int lio_vf_get_sset_count(struct net_device *netdev, int sset) 19768c2ecf20Sopenharmony_ci{ 19778c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 19788c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 19798c2ecf20Sopenharmony_ci 19808c2ecf20Sopenharmony_ci switch (sset) { 19818c2ecf20Sopenharmony_ci case ETH_SS_STATS: 19828c2ecf20Sopenharmony_ci return (ARRAY_SIZE(oct_vf_stats_strings) + 19838c2ecf20Sopenharmony_ci ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs + 19848c2ecf20Sopenharmony_ci ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs); 19858c2ecf20Sopenharmony_ci case ETH_SS_PRIV_FLAGS: 19868c2ecf20Sopenharmony_ci return lio_get_priv_flags_ss_count(lio); 19878c2ecf20Sopenharmony_ci default: 19888c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 19898c2ecf20Sopenharmony_ci } 19908c2ecf20Sopenharmony_ci} 19918c2ecf20Sopenharmony_ci 19928c2ecf20Sopenharmony_ci/* get interrupt moderation parameters */ 19938c2ecf20Sopenharmony_cistatic int octnet_get_intrmod_cfg(struct lio *lio, 19948c2ecf20Sopenharmony_ci struct oct_intrmod_cfg *intr_cfg) 19958c2ecf20Sopenharmony_ci{ 19968c2ecf20Sopenharmony_ci struct octeon_soft_command *sc; 19978c2ecf20Sopenharmony_ci struct oct_intrmod_resp *resp; 19988c2ecf20Sopenharmony_ci int retval; 19998c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 20008c2ecf20Sopenharmony_ci 20018c2ecf20Sopenharmony_ci /* Alloc soft command */ 20028c2ecf20Sopenharmony_ci sc = (struct octeon_soft_command *) 20038c2ecf20Sopenharmony_ci octeon_alloc_soft_command(oct_dev, 20048c2ecf20Sopenharmony_ci 0, 20058c2ecf20Sopenharmony_ci sizeof(struct oct_intrmod_resp), 0); 20068c2ecf20Sopenharmony_ci 20078c2ecf20Sopenharmony_ci if (!sc) 20088c2ecf20Sopenharmony_ci return -ENOMEM; 20098c2ecf20Sopenharmony_ci 20108c2ecf20Sopenharmony_ci resp = (struct oct_intrmod_resp *)sc->virtrptr; 20118c2ecf20Sopenharmony_ci memset(resp, 0, sizeof(struct oct_intrmod_resp)); 20128c2ecf20Sopenharmony_ci 20138c2ecf20Sopenharmony_ci sc->iq_no = lio->linfo.txpciq[0].s.q_no; 20148c2ecf20Sopenharmony_ci 20158c2ecf20Sopenharmony_ci octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, 20168c2ecf20Sopenharmony_ci OPCODE_NIC_INTRMOD_PARAMS, 0, 0, 0); 20178c2ecf20Sopenharmony_ci 20188c2ecf20Sopenharmony_ci init_completion(&sc->complete); 20198c2ecf20Sopenharmony_ci sc->sc_status = OCTEON_REQUEST_PENDING; 20208c2ecf20Sopenharmony_ci 20218c2ecf20Sopenharmony_ci retval = octeon_send_soft_command(oct_dev, sc); 20228c2ecf20Sopenharmony_ci if (retval == IQ_SEND_FAILED) { 20238c2ecf20Sopenharmony_ci octeon_free_soft_command(oct_dev, sc); 20248c2ecf20Sopenharmony_ci return -EINVAL; 20258c2ecf20Sopenharmony_ci } 20268c2ecf20Sopenharmony_ci 20278c2ecf20Sopenharmony_ci /* Sleep on a wait queue till the cond flag indicates that the 20288c2ecf20Sopenharmony_ci * response arrived or timed-out. 20298c2ecf20Sopenharmony_ci */ 20308c2ecf20Sopenharmony_ci retval = wait_for_sc_completion_timeout(oct_dev, sc, 0); 20318c2ecf20Sopenharmony_ci if (retval) 20328c2ecf20Sopenharmony_ci return -ENODEV; 20338c2ecf20Sopenharmony_ci 20348c2ecf20Sopenharmony_ci if (resp->status) { 20358c2ecf20Sopenharmony_ci dev_err(&oct_dev->pci_dev->dev, 20368c2ecf20Sopenharmony_ci "Get interrupt moderation parameters failed\n"); 20378c2ecf20Sopenharmony_ci WRITE_ONCE(sc->caller_is_done, true); 20388c2ecf20Sopenharmony_ci return -ENODEV; 20398c2ecf20Sopenharmony_ci } 20408c2ecf20Sopenharmony_ci 20418c2ecf20Sopenharmony_ci octeon_swap_8B_data((u64 *)&resp->intrmod, 20428c2ecf20Sopenharmony_ci (sizeof(struct oct_intrmod_cfg)) / 8); 20438c2ecf20Sopenharmony_ci memcpy(intr_cfg, &resp->intrmod, sizeof(struct oct_intrmod_cfg)); 20448c2ecf20Sopenharmony_ci WRITE_ONCE(sc->caller_is_done, true); 20458c2ecf20Sopenharmony_ci 20468c2ecf20Sopenharmony_ci return 0; 20478c2ecf20Sopenharmony_ci} 20488c2ecf20Sopenharmony_ci 20498c2ecf20Sopenharmony_ci/* Configure interrupt moderation parameters */ 20508c2ecf20Sopenharmony_cistatic int octnet_set_intrmod_cfg(struct lio *lio, 20518c2ecf20Sopenharmony_ci struct oct_intrmod_cfg *intr_cfg) 20528c2ecf20Sopenharmony_ci{ 20538c2ecf20Sopenharmony_ci struct octeon_soft_command *sc; 20548c2ecf20Sopenharmony_ci struct oct_intrmod_cfg *cfg; 20558c2ecf20Sopenharmony_ci int retval; 20568c2ecf20Sopenharmony_ci struct octeon_device *oct_dev = lio->oct_dev; 20578c2ecf20Sopenharmony_ci 20588c2ecf20Sopenharmony_ci /* Alloc soft command */ 20598c2ecf20Sopenharmony_ci sc = (struct octeon_soft_command *) 20608c2ecf20Sopenharmony_ci octeon_alloc_soft_command(oct_dev, 20618c2ecf20Sopenharmony_ci sizeof(struct oct_intrmod_cfg), 20628c2ecf20Sopenharmony_ci 16, 0); 20638c2ecf20Sopenharmony_ci 20648c2ecf20Sopenharmony_ci if (!sc) 20658c2ecf20Sopenharmony_ci return -ENOMEM; 20668c2ecf20Sopenharmony_ci 20678c2ecf20Sopenharmony_ci cfg = (struct oct_intrmod_cfg *)sc->virtdptr; 20688c2ecf20Sopenharmony_ci 20698c2ecf20Sopenharmony_ci memcpy(cfg, intr_cfg, sizeof(struct oct_intrmod_cfg)); 20708c2ecf20Sopenharmony_ci octeon_swap_8B_data((u64 *)cfg, (sizeof(struct oct_intrmod_cfg)) / 8); 20718c2ecf20Sopenharmony_ci 20728c2ecf20Sopenharmony_ci sc->iq_no = lio->linfo.txpciq[0].s.q_no; 20738c2ecf20Sopenharmony_ci 20748c2ecf20Sopenharmony_ci octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, 20758c2ecf20Sopenharmony_ci OPCODE_NIC_INTRMOD_CFG, 0, 0, 0); 20768c2ecf20Sopenharmony_ci 20778c2ecf20Sopenharmony_ci init_completion(&sc->complete); 20788c2ecf20Sopenharmony_ci sc->sc_status = OCTEON_REQUEST_PENDING; 20798c2ecf20Sopenharmony_ci 20808c2ecf20Sopenharmony_ci retval = octeon_send_soft_command(oct_dev, sc); 20818c2ecf20Sopenharmony_ci if (retval == IQ_SEND_FAILED) { 20828c2ecf20Sopenharmony_ci octeon_free_soft_command(oct_dev, sc); 20838c2ecf20Sopenharmony_ci return -EINVAL; 20848c2ecf20Sopenharmony_ci } 20858c2ecf20Sopenharmony_ci 20868c2ecf20Sopenharmony_ci /* Sleep on a wait queue till the cond flag indicates that the 20878c2ecf20Sopenharmony_ci * response arrived or timed-out. 20888c2ecf20Sopenharmony_ci */ 20898c2ecf20Sopenharmony_ci retval = wait_for_sc_completion_timeout(oct_dev, sc, 0); 20908c2ecf20Sopenharmony_ci if (retval) 20918c2ecf20Sopenharmony_ci return retval; 20928c2ecf20Sopenharmony_ci 20938c2ecf20Sopenharmony_ci retval = sc->sc_status; 20948c2ecf20Sopenharmony_ci if (retval == 0) { 20958c2ecf20Sopenharmony_ci dev_info(&oct_dev->pci_dev->dev, 20968c2ecf20Sopenharmony_ci "Rx-Adaptive Interrupt moderation %s\n", 20978c2ecf20Sopenharmony_ci (intr_cfg->rx_enable) ? 20988c2ecf20Sopenharmony_ci "enabled" : "disabled"); 20998c2ecf20Sopenharmony_ci WRITE_ONCE(sc->caller_is_done, true); 21008c2ecf20Sopenharmony_ci return 0; 21018c2ecf20Sopenharmony_ci } 21028c2ecf20Sopenharmony_ci 21038c2ecf20Sopenharmony_ci dev_err(&oct_dev->pci_dev->dev, 21048c2ecf20Sopenharmony_ci "intrmod config failed. Status: %x\n", retval); 21058c2ecf20Sopenharmony_ci WRITE_ONCE(sc->caller_is_done, true); 21068c2ecf20Sopenharmony_ci return -ENODEV; 21078c2ecf20Sopenharmony_ci} 21088c2ecf20Sopenharmony_ci 21098c2ecf20Sopenharmony_cistatic int lio_get_intr_coalesce(struct net_device *netdev, 21108c2ecf20Sopenharmony_ci struct ethtool_coalesce *intr_coal) 21118c2ecf20Sopenharmony_ci{ 21128c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 21138c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 21148c2ecf20Sopenharmony_ci struct octeon_instr_queue *iq; 21158c2ecf20Sopenharmony_ci struct oct_intrmod_cfg intrmod_cfg; 21168c2ecf20Sopenharmony_ci 21178c2ecf20Sopenharmony_ci if (octnet_get_intrmod_cfg(lio, &intrmod_cfg)) 21188c2ecf20Sopenharmony_ci return -ENODEV; 21198c2ecf20Sopenharmony_ci 21208c2ecf20Sopenharmony_ci switch (oct->chip_id) { 21218c2ecf20Sopenharmony_ci case OCTEON_CN23XX_PF_VID: 21228c2ecf20Sopenharmony_ci case OCTEON_CN23XX_VF_VID: { 21238c2ecf20Sopenharmony_ci if (!intrmod_cfg.rx_enable) { 21248c2ecf20Sopenharmony_ci intr_coal->rx_coalesce_usecs = oct->rx_coalesce_usecs; 21258c2ecf20Sopenharmony_ci intr_coal->rx_max_coalesced_frames = 21268c2ecf20Sopenharmony_ci oct->rx_max_coalesced_frames; 21278c2ecf20Sopenharmony_ci } 21288c2ecf20Sopenharmony_ci if (!intrmod_cfg.tx_enable) 21298c2ecf20Sopenharmony_ci intr_coal->tx_max_coalesced_frames = 21308c2ecf20Sopenharmony_ci oct->tx_max_coalesced_frames; 21318c2ecf20Sopenharmony_ci break; 21328c2ecf20Sopenharmony_ci } 21338c2ecf20Sopenharmony_ci case OCTEON_CN68XX: 21348c2ecf20Sopenharmony_ci case OCTEON_CN66XX: { 21358c2ecf20Sopenharmony_ci struct octeon_cn6xxx *cn6xxx = 21368c2ecf20Sopenharmony_ci (struct octeon_cn6xxx *)oct->chip; 21378c2ecf20Sopenharmony_ci 21388c2ecf20Sopenharmony_ci if (!intrmod_cfg.rx_enable) { 21398c2ecf20Sopenharmony_ci intr_coal->rx_coalesce_usecs = 21408c2ecf20Sopenharmony_ci CFG_GET_OQ_INTR_TIME(cn6xxx->conf); 21418c2ecf20Sopenharmony_ci intr_coal->rx_max_coalesced_frames = 21428c2ecf20Sopenharmony_ci CFG_GET_OQ_INTR_PKT(cn6xxx->conf); 21438c2ecf20Sopenharmony_ci } 21448c2ecf20Sopenharmony_ci iq = oct->instr_queue[lio->linfo.txpciq[0].s.q_no]; 21458c2ecf20Sopenharmony_ci intr_coal->tx_max_coalesced_frames = iq->fill_threshold; 21468c2ecf20Sopenharmony_ci break; 21478c2ecf20Sopenharmony_ci } 21488c2ecf20Sopenharmony_ci default: 21498c2ecf20Sopenharmony_ci netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n"); 21508c2ecf20Sopenharmony_ci return -EINVAL; 21518c2ecf20Sopenharmony_ci } 21528c2ecf20Sopenharmony_ci if (intrmod_cfg.rx_enable) { 21538c2ecf20Sopenharmony_ci intr_coal->use_adaptive_rx_coalesce = 21548c2ecf20Sopenharmony_ci intrmod_cfg.rx_enable; 21558c2ecf20Sopenharmony_ci intr_coal->rate_sample_interval = 21568c2ecf20Sopenharmony_ci intrmod_cfg.check_intrvl; 21578c2ecf20Sopenharmony_ci intr_coal->pkt_rate_high = 21588c2ecf20Sopenharmony_ci intrmod_cfg.maxpkt_ratethr; 21598c2ecf20Sopenharmony_ci intr_coal->pkt_rate_low = 21608c2ecf20Sopenharmony_ci intrmod_cfg.minpkt_ratethr; 21618c2ecf20Sopenharmony_ci intr_coal->rx_max_coalesced_frames_high = 21628c2ecf20Sopenharmony_ci intrmod_cfg.rx_maxcnt_trigger; 21638c2ecf20Sopenharmony_ci intr_coal->rx_coalesce_usecs_high = 21648c2ecf20Sopenharmony_ci intrmod_cfg.rx_maxtmr_trigger; 21658c2ecf20Sopenharmony_ci intr_coal->rx_coalesce_usecs_low = 21668c2ecf20Sopenharmony_ci intrmod_cfg.rx_mintmr_trigger; 21678c2ecf20Sopenharmony_ci intr_coal->rx_max_coalesced_frames_low = 21688c2ecf20Sopenharmony_ci intrmod_cfg.rx_mincnt_trigger; 21698c2ecf20Sopenharmony_ci } 21708c2ecf20Sopenharmony_ci if ((OCTEON_CN23XX_PF(oct) || OCTEON_CN23XX_VF(oct)) && 21718c2ecf20Sopenharmony_ci (intrmod_cfg.tx_enable)) { 21728c2ecf20Sopenharmony_ci intr_coal->use_adaptive_tx_coalesce = 21738c2ecf20Sopenharmony_ci intrmod_cfg.tx_enable; 21748c2ecf20Sopenharmony_ci intr_coal->tx_max_coalesced_frames_high = 21758c2ecf20Sopenharmony_ci intrmod_cfg.tx_maxcnt_trigger; 21768c2ecf20Sopenharmony_ci intr_coal->tx_max_coalesced_frames_low = 21778c2ecf20Sopenharmony_ci intrmod_cfg.tx_mincnt_trigger; 21788c2ecf20Sopenharmony_ci } 21798c2ecf20Sopenharmony_ci return 0; 21808c2ecf20Sopenharmony_ci} 21818c2ecf20Sopenharmony_ci 21828c2ecf20Sopenharmony_ci/* Enable/Disable auto interrupt Moderation */ 21838c2ecf20Sopenharmony_cistatic int oct_cfg_adaptive_intr(struct lio *lio, 21848c2ecf20Sopenharmony_ci struct oct_intrmod_cfg *intrmod_cfg, 21858c2ecf20Sopenharmony_ci struct ethtool_coalesce *intr_coal) 21868c2ecf20Sopenharmony_ci{ 21878c2ecf20Sopenharmony_ci int ret = 0; 21888c2ecf20Sopenharmony_ci 21898c2ecf20Sopenharmony_ci if (intrmod_cfg->rx_enable || intrmod_cfg->tx_enable) { 21908c2ecf20Sopenharmony_ci intrmod_cfg->check_intrvl = intr_coal->rate_sample_interval; 21918c2ecf20Sopenharmony_ci intrmod_cfg->maxpkt_ratethr = intr_coal->pkt_rate_high; 21928c2ecf20Sopenharmony_ci intrmod_cfg->minpkt_ratethr = intr_coal->pkt_rate_low; 21938c2ecf20Sopenharmony_ci } 21948c2ecf20Sopenharmony_ci if (intrmod_cfg->rx_enable) { 21958c2ecf20Sopenharmony_ci intrmod_cfg->rx_maxcnt_trigger = 21968c2ecf20Sopenharmony_ci intr_coal->rx_max_coalesced_frames_high; 21978c2ecf20Sopenharmony_ci intrmod_cfg->rx_maxtmr_trigger = 21988c2ecf20Sopenharmony_ci intr_coal->rx_coalesce_usecs_high; 21998c2ecf20Sopenharmony_ci intrmod_cfg->rx_mintmr_trigger = 22008c2ecf20Sopenharmony_ci intr_coal->rx_coalesce_usecs_low; 22018c2ecf20Sopenharmony_ci intrmod_cfg->rx_mincnt_trigger = 22028c2ecf20Sopenharmony_ci intr_coal->rx_max_coalesced_frames_low; 22038c2ecf20Sopenharmony_ci } 22048c2ecf20Sopenharmony_ci if (intrmod_cfg->tx_enable) { 22058c2ecf20Sopenharmony_ci intrmod_cfg->tx_maxcnt_trigger = 22068c2ecf20Sopenharmony_ci intr_coal->tx_max_coalesced_frames_high; 22078c2ecf20Sopenharmony_ci intrmod_cfg->tx_mincnt_trigger = 22088c2ecf20Sopenharmony_ci intr_coal->tx_max_coalesced_frames_low; 22098c2ecf20Sopenharmony_ci } 22108c2ecf20Sopenharmony_ci 22118c2ecf20Sopenharmony_ci ret = octnet_set_intrmod_cfg(lio, intrmod_cfg); 22128c2ecf20Sopenharmony_ci 22138c2ecf20Sopenharmony_ci return ret; 22148c2ecf20Sopenharmony_ci} 22158c2ecf20Sopenharmony_ci 22168c2ecf20Sopenharmony_cistatic int 22178c2ecf20Sopenharmony_cioct_cfg_rx_intrcnt(struct lio *lio, 22188c2ecf20Sopenharmony_ci struct oct_intrmod_cfg *intrmod, 22198c2ecf20Sopenharmony_ci struct ethtool_coalesce *intr_coal) 22208c2ecf20Sopenharmony_ci{ 22218c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 22228c2ecf20Sopenharmony_ci u32 rx_max_coalesced_frames; 22238c2ecf20Sopenharmony_ci 22248c2ecf20Sopenharmony_ci /* Config Cnt based interrupt values */ 22258c2ecf20Sopenharmony_ci switch (oct->chip_id) { 22268c2ecf20Sopenharmony_ci case OCTEON_CN68XX: 22278c2ecf20Sopenharmony_ci case OCTEON_CN66XX: { 22288c2ecf20Sopenharmony_ci struct octeon_cn6xxx *cn6xxx = 22298c2ecf20Sopenharmony_ci (struct octeon_cn6xxx *)oct->chip; 22308c2ecf20Sopenharmony_ci 22318c2ecf20Sopenharmony_ci if (!intr_coal->rx_max_coalesced_frames) 22328c2ecf20Sopenharmony_ci rx_max_coalesced_frames = CN6XXX_OQ_INTR_PKT; 22338c2ecf20Sopenharmony_ci else 22348c2ecf20Sopenharmony_ci rx_max_coalesced_frames = 22358c2ecf20Sopenharmony_ci intr_coal->rx_max_coalesced_frames; 22368c2ecf20Sopenharmony_ci octeon_write_csr(oct, CN6XXX_SLI_OQ_INT_LEVEL_PKTS, 22378c2ecf20Sopenharmony_ci rx_max_coalesced_frames); 22388c2ecf20Sopenharmony_ci CFG_SET_OQ_INTR_PKT(cn6xxx->conf, rx_max_coalesced_frames); 22398c2ecf20Sopenharmony_ci break; 22408c2ecf20Sopenharmony_ci } 22418c2ecf20Sopenharmony_ci case OCTEON_CN23XX_PF_VID: { 22428c2ecf20Sopenharmony_ci int q_no; 22438c2ecf20Sopenharmony_ci 22448c2ecf20Sopenharmony_ci if (!intr_coal->rx_max_coalesced_frames) 22458c2ecf20Sopenharmony_ci rx_max_coalesced_frames = intrmod->rx_frames; 22468c2ecf20Sopenharmony_ci else 22478c2ecf20Sopenharmony_ci rx_max_coalesced_frames = 22488c2ecf20Sopenharmony_ci intr_coal->rx_max_coalesced_frames; 22498c2ecf20Sopenharmony_ci for (q_no = 0; q_no < oct->num_oqs; q_no++) { 22508c2ecf20Sopenharmony_ci q_no += oct->sriov_info.pf_srn; 22518c2ecf20Sopenharmony_ci octeon_write_csr64( 22528c2ecf20Sopenharmony_ci oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no), 22538c2ecf20Sopenharmony_ci (octeon_read_csr64( 22548c2ecf20Sopenharmony_ci oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no)) & 22558c2ecf20Sopenharmony_ci (0x3fffff00000000UL)) | 22568c2ecf20Sopenharmony_ci (rx_max_coalesced_frames - 1)); 22578c2ecf20Sopenharmony_ci /*consider setting resend bit*/ 22588c2ecf20Sopenharmony_ci } 22598c2ecf20Sopenharmony_ci intrmod->rx_frames = rx_max_coalesced_frames; 22608c2ecf20Sopenharmony_ci oct->rx_max_coalesced_frames = rx_max_coalesced_frames; 22618c2ecf20Sopenharmony_ci break; 22628c2ecf20Sopenharmony_ci } 22638c2ecf20Sopenharmony_ci case OCTEON_CN23XX_VF_VID: { 22648c2ecf20Sopenharmony_ci int q_no; 22658c2ecf20Sopenharmony_ci 22668c2ecf20Sopenharmony_ci if (!intr_coal->rx_max_coalesced_frames) 22678c2ecf20Sopenharmony_ci rx_max_coalesced_frames = intrmod->rx_frames; 22688c2ecf20Sopenharmony_ci else 22698c2ecf20Sopenharmony_ci rx_max_coalesced_frames = 22708c2ecf20Sopenharmony_ci intr_coal->rx_max_coalesced_frames; 22718c2ecf20Sopenharmony_ci for (q_no = 0; q_no < oct->num_oqs; q_no++) { 22728c2ecf20Sopenharmony_ci octeon_write_csr64( 22738c2ecf20Sopenharmony_ci oct, CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(q_no), 22748c2ecf20Sopenharmony_ci (octeon_read_csr64( 22758c2ecf20Sopenharmony_ci oct, CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(q_no)) & 22768c2ecf20Sopenharmony_ci (0x3fffff00000000UL)) | 22778c2ecf20Sopenharmony_ci (rx_max_coalesced_frames - 1)); 22788c2ecf20Sopenharmony_ci /*consider writing to resend bit here*/ 22798c2ecf20Sopenharmony_ci } 22808c2ecf20Sopenharmony_ci intrmod->rx_frames = rx_max_coalesced_frames; 22818c2ecf20Sopenharmony_ci oct->rx_max_coalesced_frames = rx_max_coalesced_frames; 22828c2ecf20Sopenharmony_ci break; 22838c2ecf20Sopenharmony_ci } 22848c2ecf20Sopenharmony_ci default: 22858c2ecf20Sopenharmony_ci return -EINVAL; 22868c2ecf20Sopenharmony_ci } 22878c2ecf20Sopenharmony_ci return 0; 22888c2ecf20Sopenharmony_ci} 22898c2ecf20Sopenharmony_ci 22908c2ecf20Sopenharmony_cistatic int oct_cfg_rx_intrtime(struct lio *lio, 22918c2ecf20Sopenharmony_ci struct oct_intrmod_cfg *intrmod, 22928c2ecf20Sopenharmony_ci struct ethtool_coalesce *intr_coal) 22938c2ecf20Sopenharmony_ci{ 22948c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 22958c2ecf20Sopenharmony_ci u32 time_threshold, rx_coalesce_usecs; 22968c2ecf20Sopenharmony_ci 22978c2ecf20Sopenharmony_ci /* Config Time based interrupt values */ 22988c2ecf20Sopenharmony_ci switch (oct->chip_id) { 22998c2ecf20Sopenharmony_ci case OCTEON_CN68XX: 23008c2ecf20Sopenharmony_ci case OCTEON_CN66XX: { 23018c2ecf20Sopenharmony_ci struct octeon_cn6xxx *cn6xxx = 23028c2ecf20Sopenharmony_ci (struct octeon_cn6xxx *)oct->chip; 23038c2ecf20Sopenharmony_ci if (!intr_coal->rx_coalesce_usecs) 23048c2ecf20Sopenharmony_ci rx_coalesce_usecs = CN6XXX_OQ_INTR_TIME; 23058c2ecf20Sopenharmony_ci else 23068c2ecf20Sopenharmony_ci rx_coalesce_usecs = intr_coal->rx_coalesce_usecs; 23078c2ecf20Sopenharmony_ci 23088c2ecf20Sopenharmony_ci time_threshold = lio_cn6xxx_get_oq_ticks(oct, 23098c2ecf20Sopenharmony_ci rx_coalesce_usecs); 23108c2ecf20Sopenharmony_ci octeon_write_csr(oct, 23118c2ecf20Sopenharmony_ci CN6XXX_SLI_OQ_INT_LEVEL_TIME, 23128c2ecf20Sopenharmony_ci time_threshold); 23138c2ecf20Sopenharmony_ci 23148c2ecf20Sopenharmony_ci CFG_SET_OQ_INTR_TIME(cn6xxx->conf, rx_coalesce_usecs); 23158c2ecf20Sopenharmony_ci break; 23168c2ecf20Sopenharmony_ci } 23178c2ecf20Sopenharmony_ci case OCTEON_CN23XX_PF_VID: { 23188c2ecf20Sopenharmony_ci u64 time_threshold; 23198c2ecf20Sopenharmony_ci int q_no; 23208c2ecf20Sopenharmony_ci 23218c2ecf20Sopenharmony_ci if (!intr_coal->rx_coalesce_usecs) 23228c2ecf20Sopenharmony_ci rx_coalesce_usecs = intrmod->rx_usecs; 23238c2ecf20Sopenharmony_ci else 23248c2ecf20Sopenharmony_ci rx_coalesce_usecs = intr_coal->rx_coalesce_usecs; 23258c2ecf20Sopenharmony_ci time_threshold = 23268c2ecf20Sopenharmony_ci cn23xx_pf_get_oq_ticks(oct, (u32)rx_coalesce_usecs); 23278c2ecf20Sopenharmony_ci for (q_no = 0; q_no < oct->num_oqs; q_no++) { 23288c2ecf20Sopenharmony_ci q_no += oct->sriov_info.pf_srn; 23298c2ecf20Sopenharmony_ci octeon_write_csr64(oct, 23308c2ecf20Sopenharmony_ci CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no), 23318c2ecf20Sopenharmony_ci (intrmod->rx_frames | 23328c2ecf20Sopenharmony_ci ((u64)time_threshold << 32))); 23338c2ecf20Sopenharmony_ci /*consider writing to resend bit here*/ 23348c2ecf20Sopenharmony_ci } 23358c2ecf20Sopenharmony_ci intrmod->rx_usecs = rx_coalesce_usecs; 23368c2ecf20Sopenharmony_ci oct->rx_coalesce_usecs = rx_coalesce_usecs; 23378c2ecf20Sopenharmony_ci break; 23388c2ecf20Sopenharmony_ci } 23398c2ecf20Sopenharmony_ci case OCTEON_CN23XX_VF_VID: { 23408c2ecf20Sopenharmony_ci u64 time_threshold; 23418c2ecf20Sopenharmony_ci int q_no; 23428c2ecf20Sopenharmony_ci 23438c2ecf20Sopenharmony_ci if (!intr_coal->rx_coalesce_usecs) 23448c2ecf20Sopenharmony_ci rx_coalesce_usecs = intrmod->rx_usecs; 23458c2ecf20Sopenharmony_ci else 23468c2ecf20Sopenharmony_ci rx_coalesce_usecs = intr_coal->rx_coalesce_usecs; 23478c2ecf20Sopenharmony_ci 23488c2ecf20Sopenharmony_ci time_threshold = 23498c2ecf20Sopenharmony_ci cn23xx_vf_get_oq_ticks(oct, (u32)rx_coalesce_usecs); 23508c2ecf20Sopenharmony_ci for (q_no = 0; q_no < oct->num_oqs; q_no++) { 23518c2ecf20Sopenharmony_ci octeon_write_csr64( 23528c2ecf20Sopenharmony_ci oct, CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(q_no), 23538c2ecf20Sopenharmony_ci (intrmod->rx_frames | 23548c2ecf20Sopenharmony_ci ((u64)time_threshold << 32))); 23558c2ecf20Sopenharmony_ci /*consider setting resend bit*/ 23568c2ecf20Sopenharmony_ci } 23578c2ecf20Sopenharmony_ci intrmod->rx_usecs = rx_coalesce_usecs; 23588c2ecf20Sopenharmony_ci oct->rx_coalesce_usecs = rx_coalesce_usecs; 23598c2ecf20Sopenharmony_ci break; 23608c2ecf20Sopenharmony_ci } 23618c2ecf20Sopenharmony_ci default: 23628c2ecf20Sopenharmony_ci return -EINVAL; 23638c2ecf20Sopenharmony_ci } 23648c2ecf20Sopenharmony_ci 23658c2ecf20Sopenharmony_ci return 0; 23668c2ecf20Sopenharmony_ci} 23678c2ecf20Sopenharmony_ci 23688c2ecf20Sopenharmony_cistatic int 23698c2ecf20Sopenharmony_cioct_cfg_tx_intrcnt(struct lio *lio, 23708c2ecf20Sopenharmony_ci struct oct_intrmod_cfg *intrmod, 23718c2ecf20Sopenharmony_ci struct ethtool_coalesce *intr_coal) 23728c2ecf20Sopenharmony_ci{ 23738c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 23748c2ecf20Sopenharmony_ci u32 iq_intr_pkt; 23758c2ecf20Sopenharmony_ci void __iomem *inst_cnt_reg; 23768c2ecf20Sopenharmony_ci u64 val; 23778c2ecf20Sopenharmony_ci 23788c2ecf20Sopenharmony_ci /* Config Cnt based interrupt values */ 23798c2ecf20Sopenharmony_ci switch (oct->chip_id) { 23808c2ecf20Sopenharmony_ci case OCTEON_CN68XX: 23818c2ecf20Sopenharmony_ci case OCTEON_CN66XX: 23828c2ecf20Sopenharmony_ci break; 23838c2ecf20Sopenharmony_ci case OCTEON_CN23XX_VF_VID: 23848c2ecf20Sopenharmony_ci case OCTEON_CN23XX_PF_VID: { 23858c2ecf20Sopenharmony_ci int q_no; 23868c2ecf20Sopenharmony_ci 23878c2ecf20Sopenharmony_ci if (!intr_coal->tx_max_coalesced_frames) 23888c2ecf20Sopenharmony_ci iq_intr_pkt = CN23XX_DEF_IQ_INTR_THRESHOLD & 23898c2ecf20Sopenharmony_ci CN23XX_PKT_IN_DONE_WMARK_MASK; 23908c2ecf20Sopenharmony_ci else 23918c2ecf20Sopenharmony_ci iq_intr_pkt = intr_coal->tx_max_coalesced_frames & 23928c2ecf20Sopenharmony_ci CN23XX_PKT_IN_DONE_WMARK_MASK; 23938c2ecf20Sopenharmony_ci for (q_no = 0; q_no < oct->num_iqs; q_no++) { 23948c2ecf20Sopenharmony_ci inst_cnt_reg = (oct->instr_queue[q_no])->inst_cnt_reg; 23958c2ecf20Sopenharmony_ci val = readq(inst_cnt_reg); 23968c2ecf20Sopenharmony_ci /*clear wmark and count.dont want to write count back*/ 23978c2ecf20Sopenharmony_ci val = (val & 0xFFFF000000000000ULL) | 23988c2ecf20Sopenharmony_ci ((u64)(iq_intr_pkt - 1) 23998c2ecf20Sopenharmony_ci << CN23XX_PKT_IN_DONE_WMARK_BIT_POS); 24008c2ecf20Sopenharmony_ci writeq(val, inst_cnt_reg); 24018c2ecf20Sopenharmony_ci /*consider setting resend bit*/ 24028c2ecf20Sopenharmony_ci } 24038c2ecf20Sopenharmony_ci intrmod->tx_frames = iq_intr_pkt; 24048c2ecf20Sopenharmony_ci oct->tx_max_coalesced_frames = iq_intr_pkt; 24058c2ecf20Sopenharmony_ci break; 24068c2ecf20Sopenharmony_ci } 24078c2ecf20Sopenharmony_ci default: 24088c2ecf20Sopenharmony_ci return -EINVAL; 24098c2ecf20Sopenharmony_ci } 24108c2ecf20Sopenharmony_ci return 0; 24118c2ecf20Sopenharmony_ci} 24128c2ecf20Sopenharmony_ci 24138c2ecf20Sopenharmony_cistatic int lio_set_intr_coalesce(struct net_device *netdev, 24148c2ecf20Sopenharmony_ci struct ethtool_coalesce *intr_coal) 24158c2ecf20Sopenharmony_ci{ 24168c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 24178c2ecf20Sopenharmony_ci int ret; 24188c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 24198c2ecf20Sopenharmony_ci struct oct_intrmod_cfg intrmod = {0}; 24208c2ecf20Sopenharmony_ci u32 j, q_no; 24218c2ecf20Sopenharmony_ci int db_max, db_min; 24228c2ecf20Sopenharmony_ci 24238c2ecf20Sopenharmony_ci switch (oct->chip_id) { 24248c2ecf20Sopenharmony_ci case OCTEON_CN68XX: 24258c2ecf20Sopenharmony_ci case OCTEON_CN66XX: 24268c2ecf20Sopenharmony_ci db_min = CN6XXX_DB_MIN; 24278c2ecf20Sopenharmony_ci db_max = CN6XXX_DB_MAX; 24288c2ecf20Sopenharmony_ci if ((intr_coal->tx_max_coalesced_frames >= db_min) && 24298c2ecf20Sopenharmony_ci (intr_coal->tx_max_coalesced_frames <= db_max)) { 24308c2ecf20Sopenharmony_ci for (j = 0; j < lio->linfo.num_txpciq; j++) { 24318c2ecf20Sopenharmony_ci q_no = lio->linfo.txpciq[j].s.q_no; 24328c2ecf20Sopenharmony_ci oct->instr_queue[q_no]->fill_threshold = 24338c2ecf20Sopenharmony_ci intr_coal->tx_max_coalesced_frames; 24348c2ecf20Sopenharmony_ci } 24358c2ecf20Sopenharmony_ci } else { 24368c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, 24378c2ecf20Sopenharmony_ci "LIQUIDIO: Invalid tx-frames:%d. Range is min:%d max:%d\n", 24388c2ecf20Sopenharmony_ci intr_coal->tx_max_coalesced_frames, 24398c2ecf20Sopenharmony_ci db_min, db_max); 24408c2ecf20Sopenharmony_ci return -EINVAL; 24418c2ecf20Sopenharmony_ci } 24428c2ecf20Sopenharmony_ci break; 24438c2ecf20Sopenharmony_ci case OCTEON_CN23XX_PF_VID: 24448c2ecf20Sopenharmony_ci case OCTEON_CN23XX_VF_VID: 24458c2ecf20Sopenharmony_ci break; 24468c2ecf20Sopenharmony_ci default: 24478c2ecf20Sopenharmony_ci return -EINVAL; 24488c2ecf20Sopenharmony_ci } 24498c2ecf20Sopenharmony_ci 24508c2ecf20Sopenharmony_ci intrmod.rx_enable = intr_coal->use_adaptive_rx_coalesce ? 1 : 0; 24518c2ecf20Sopenharmony_ci intrmod.tx_enable = intr_coal->use_adaptive_tx_coalesce ? 1 : 0; 24528c2ecf20Sopenharmony_ci intrmod.rx_frames = CFG_GET_OQ_INTR_PKT(octeon_get_conf(oct)); 24538c2ecf20Sopenharmony_ci intrmod.rx_usecs = CFG_GET_OQ_INTR_TIME(octeon_get_conf(oct)); 24548c2ecf20Sopenharmony_ci intrmod.tx_frames = CFG_GET_IQ_INTR_PKT(octeon_get_conf(oct)); 24558c2ecf20Sopenharmony_ci 24568c2ecf20Sopenharmony_ci ret = oct_cfg_adaptive_intr(lio, &intrmod, intr_coal); 24578c2ecf20Sopenharmony_ci 24588c2ecf20Sopenharmony_ci if (!intr_coal->use_adaptive_rx_coalesce) { 24598c2ecf20Sopenharmony_ci ret = oct_cfg_rx_intrtime(lio, &intrmod, intr_coal); 24608c2ecf20Sopenharmony_ci if (ret) 24618c2ecf20Sopenharmony_ci goto ret_intrmod; 24628c2ecf20Sopenharmony_ci 24638c2ecf20Sopenharmony_ci ret = oct_cfg_rx_intrcnt(lio, &intrmod, intr_coal); 24648c2ecf20Sopenharmony_ci if (ret) 24658c2ecf20Sopenharmony_ci goto ret_intrmod; 24668c2ecf20Sopenharmony_ci } else { 24678c2ecf20Sopenharmony_ci oct->rx_coalesce_usecs = 24688c2ecf20Sopenharmony_ci CFG_GET_OQ_INTR_TIME(octeon_get_conf(oct)); 24698c2ecf20Sopenharmony_ci oct->rx_max_coalesced_frames = 24708c2ecf20Sopenharmony_ci CFG_GET_OQ_INTR_PKT(octeon_get_conf(oct)); 24718c2ecf20Sopenharmony_ci } 24728c2ecf20Sopenharmony_ci 24738c2ecf20Sopenharmony_ci if (!intr_coal->use_adaptive_tx_coalesce) { 24748c2ecf20Sopenharmony_ci ret = oct_cfg_tx_intrcnt(lio, &intrmod, intr_coal); 24758c2ecf20Sopenharmony_ci if (ret) 24768c2ecf20Sopenharmony_ci goto ret_intrmod; 24778c2ecf20Sopenharmony_ci } else { 24788c2ecf20Sopenharmony_ci oct->tx_max_coalesced_frames = 24798c2ecf20Sopenharmony_ci CFG_GET_IQ_INTR_PKT(octeon_get_conf(oct)); 24808c2ecf20Sopenharmony_ci } 24818c2ecf20Sopenharmony_ci 24828c2ecf20Sopenharmony_ci return 0; 24838c2ecf20Sopenharmony_ciret_intrmod: 24848c2ecf20Sopenharmony_ci return ret; 24858c2ecf20Sopenharmony_ci} 24868c2ecf20Sopenharmony_ci 24878c2ecf20Sopenharmony_cistatic int lio_get_ts_info(struct net_device *netdev, 24888c2ecf20Sopenharmony_ci struct ethtool_ts_info *info) 24898c2ecf20Sopenharmony_ci{ 24908c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 24918c2ecf20Sopenharmony_ci 24928c2ecf20Sopenharmony_ci info->so_timestamping = 24938c2ecf20Sopenharmony_ci#ifdef PTP_HARDWARE_TIMESTAMPING 24948c2ecf20Sopenharmony_ci SOF_TIMESTAMPING_TX_HARDWARE | 24958c2ecf20Sopenharmony_ci SOF_TIMESTAMPING_RX_HARDWARE | 24968c2ecf20Sopenharmony_ci SOF_TIMESTAMPING_RAW_HARDWARE | 24978c2ecf20Sopenharmony_ci SOF_TIMESTAMPING_TX_SOFTWARE | 24988c2ecf20Sopenharmony_ci#endif 24998c2ecf20Sopenharmony_ci SOF_TIMESTAMPING_RX_SOFTWARE | 25008c2ecf20Sopenharmony_ci SOF_TIMESTAMPING_SOFTWARE; 25018c2ecf20Sopenharmony_ci 25028c2ecf20Sopenharmony_ci if (lio->ptp_clock) 25038c2ecf20Sopenharmony_ci info->phc_index = ptp_clock_index(lio->ptp_clock); 25048c2ecf20Sopenharmony_ci else 25058c2ecf20Sopenharmony_ci info->phc_index = -1; 25068c2ecf20Sopenharmony_ci 25078c2ecf20Sopenharmony_ci#ifdef PTP_HARDWARE_TIMESTAMPING 25088c2ecf20Sopenharmony_ci info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); 25098c2ecf20Sopenharmony_ci 25108c2ecf20Sopenharmony_ci info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) | 25118c2ecf20Sopenharmony_ci (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) | 25128c2ecf20Sopenharmony_ci (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | 25138c2ecf20Sopenharmony_ci (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT); 25148c2ecf20Sopenharmony_ci#endif 25158c2ecf20Sopenharmony_ci 25168c2ecf20Sopenharmony_ci return 0; 25178c2ecf20Sopenharmony_ci} 25188c2ecf20Sopenharmony_ci 25198c2ecf20Sopenharmony_ci/* Return register dump len. */ 25208c2ecf20Sopenharmony_cistatic int lio_get_regs_len(struct net_device *dev) 25218c2ecf20Sopenharmony_ci{ 25228c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(dev); 25238c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 25248c2ecf20Sopenharmony_ci 25258c2ecf20Sopenharmony_ci switch (oct->chip_id) { 25268c2ecf20Sopenharmony_ci case OCTEON_CN23XX_PF_VID: 25278c2ecf20Sopenharmony_ci return OCT_ETHTOOL_REGDUMP_LEN_23XX; 25288c2ecf20Sopenharmony_ci case OCTEON_CN23XX_VF_VID: 25298c2ecf20Sopenharmony_ci return OCT_ETHTOOL_REGDUMP_LEN_23XX_VF; 25308c2ecf20Sopenharmony_ci default: 25318c2ecf20Sopenharmony_ci return OCT_ETHTOOL_REGDUMP_LEN; 25328c2ecf20Sopenharmony_ci } 25338c2ecf20Sopenharmony_ci} 25348c2ecf20Sopenharmony_ci 25358c2ecf20Sopenharmony_cistatic int cn23xx_read_csr_reg(char *s, struct octeon_device *oct) 25368c2ecf20Sopenharmony_ci{ 25378c2ecf20Sopenharmony_ci u32 reg; 25388c2ecf20Sopenharmony_ci u8 pf_num = oct->pf_num; 25398c2ecf20Sopenharmony_ci int len = 0; 25408c2ecf20Sopenharmony_ci int i; 25418c2ecf20Sopenharmony_ci 25428c2ecf20Sopenharmony_ci /* PCI Window Registers */ 25438c2ecf20Sopenharmony_ci 25448c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n"); 25458c2ecf20Sopenharmony_ci 25468c2ecf20Sopenharmony_ci /*0x29030 or 0x29040*/ 25478c2ecf20Sopenharmony_ci reg = CN23XX_SLI_PKT_MAC_RINFO64(oct->pcie_port, oct->pf_num); 25488c2ecf20Sopenharmony_ci len += sprintf(s + len, 25498c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT_MAC%d_PF%d_RINFO): %016llx\n", 25508c2ecf20Sopenharmony_ci reg, oct->pcie_port, oct->pf_num, 25518c2ecf20Sopenharmony_ci (u64)octeon_read_csr64(oct, reg)); 25528c2ecf20Sopenharmony_ci 25538c2ecf20Sopenharmony_ci /*0x27080 or 0x27090*/ 25548c2ecf20Sopenharmony_ci reg = CN23XX_SLI_MAC_PF_INT_ENB64(oct->pcie_port, oct->pf_num); 25558c2ecf20Sopenharmony_ci len += 25568c2ecf20Sopenharmony_ci sprintf(s + len, "\n[%08x] (SLI_MAC%d_PF%d_INT_ENB): %016llx\n", 25578c2ecf20Sopenharmony_ci reg, oct->pcie_port, oct->pf_num, 25588c2ecf20Sopenharmony_ci (u64)octeon_read_csr64(oct, reg)); 25598c2ecf20Sopenharmony_ci 25608c2ecf20Sopenharmony_ci /*0x27000 or 0x27010*/ 25618c2ecf20Sopenharmony_ci reg = CN23XX_SLI_MAC_PF_INT_SUM64(oct->pcie_port, oct->pf_num); 25628c2ecf20Sopenharmony_ci len += 25638c2ecf20Sopenharmony_ci sprintf(s + len, "\n[%08x] (SLI_MAC%d_PF%d_INT_SUM): %016llx\n", 25648c2ecf20Sopenharmony_ci reg, oct->pcie_port, oct->pf_num, 25658c2ecf20Sopenharmony_ci (u64)octeon_read_csr64(oct, reg)); 25668c2ecf20Sopenharmony_ci 25678c2ecf20Sopenharmony_ci /*0x29120*/ 25688c2ecf20Sopenharmony_ci reg = 0x29120; 25698c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%08x] (SLI_PKT_MEM_CTL): %016llx\n", reg, 25708c2ecf20Sopenharmony_ci (u64)octeon_read_csr64(oct, reg)); 25718c2ecf20Sopenharmony_ci 25728c2ecf20Sopenharmony_ci /*0x27300*/ 25738c2ecf20Sopenharmony_ci reg = 0x27300 + oct->pcie_port * CN23XX_MAC_INT_OFFSET + 25748c2ecf20Sopenharmony_ci (oct->pf_num) * CN23XX_PF_INT_OFFSET; 25758c2ecf20Sopenharmony_ci len += sprintf( 25768c2ecf20Sopenharmony_ci s + len, "\n[%08x] (SLI_MAC%d_PF%d_PKT_VF_INT): %016llx\n", reg, 25778c2ecf20Sopenharmony_ci oct->pcie_port, oct->pf_num, (u64)octeon_read_csr64(oct, reg)); 25788c2ecf20Sopenharmony_ci 25798c2ecf20Sopenharmony_ci /*0x27200*/ 25808c2ecf20Sopenharmony_ci reg = 0x27200 + oct->pcie_port * CN23XX_MAC_INT_OFFSET + 25818c2ecf20Sopenharmony_ci (oct->pf_num) * CN23XX_PF_INT_OFFSET; 25828c2ecf20Sopenharmony_ci len += sprintf(s + len, 25838c2ecf20Sopenharmony_ci "\n[%08x] (SLI_MAC%d_PF%d_PP_VF_INT): %016llx\n", 25848c2ecf20Sopenharmony_ci reg, oct->pcie_port, oct->pf_num, 25858c2ecf20Sopenharmony_ci (u64)octeon_read_csr64(oct, reg)); 25868c2ecf20Sopenharmony_ci 25878c2ecf20Sopenharmony_ci /*29130*/ 25888c2ecf20Sopenharmony_ci reg = CN23XX_SLI_PKT_CNT_INT; 25898c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%08x] (SLI_PKT_CNT_INT): %016llx\n", reg, 25908c2ecf20Sopenharmony_ci (u64)octeon_read_csr64(oct, reg)); 25918c2ecf20Sopenharmony_ci 25928c2ecf20Sopenharmony_ci /*0x29140*/ 25938c2ecf20Sopenharmony_ci reg = CN23XX_SLI_PKT_TIME_INT; 25948c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%08x] (SLI_PKT_TIME_INT): %016llx\n", reg, 25958c2ecf20Sopenharmony_ci (u64)octeon_read_csr64(oct, reg)); 25968c2ecf20Sopenharmony_ci 25978c2ecf20Sopenharmony_ci /*0x29160*/ 25988c2ecf20Sopenharmony_ci reg = 0x29160; 25998c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%08x] (SLI_PKT_INT): %016llx\n", reg, 26008c2ecf20Sopenharmony_ci (u64)octeon_read_csr64(oct, reg)); 26018c2ecf20Sopenharmony_ci 26028c2ecf20Sopenharmony_ci /*0x29180*/ 26038c2ecf20Sopenharmony_ci reg = CN23XX_SLI_OQ_WMARK; 26048c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%08x] (SLI_PKT_OUTPUT_WMARK): %016llx\n", 26058c2ecf20Sopenharmony_ci reg, (u64)octeon_read_csr64(oct, reg)); 26068c2ecf20Sopenharmony_ci 26078c2ecf20Sopenharmony_ci /*0x291E0*/ 26088c2ecf20Sopenharmony_ci reg = CN23XX_SLI_PKT_IOQ_RING_RST; 26098c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%08x] (SLI_PKT_RING_RST): %016llx\n", reg, 26108c2ecf20Sopenharmony_ci (u64)octeon_read_csr64(oct, reg)); 26118c2ecf20Sopenharmony_ci 26128c2ecf20Sopenharmony_ci /*0x29210*/ 26138c2ecf20Sopenharmony_ci reg = CN23XX_SLI_GBL_CONTROL; 26148c2ecf20Sopenharmony_ci len += sprintf(s + len, 26158c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT_GBL_CONTROL): %016llx\n", reg, 26168c2ecf20Sopenharmony_ci (u64)octeon_read_csr64(oct, reg)); 26178c2ecf20Sopenharmony_ci 26188c2ecf20Sopenharmony_ci /*0x29220*/ 26198c2ecf20Sopenharmony_ci reg = 0x29220; 26208c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%08x] (SLI_PKT_BIST_STATUS): %016llx\n", 26218c2ecf20Sopenharmony_ci reg, (u64)octeon_read_csr64(oct, reg)); 26228c2ecf20Sopenharmony_ci 26238c2ecf20Sopenharmony_ci /*PF only*/ 26248c2ecf20Sopenharmony_ci if (pf_num == 0) { 26258c2ecf20Sopenharmony_ci /*0x29260*/ 26268c2ecf20Sopenharmony_ci reg = CN23XX_SLI_OUT_BP_EN_W1S; 26278c2ecf20Sopenharmony_ci len += sprintf(s + len, 26288c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT_OUT_BP_EN_W1S): %016llx\n", 26298c2ecf20Sopenharmony_ci reg, (u64)octeon_read_csr64(oct, reg)); 26308c2ecf20Sopenharmony_ci } else if (pf_num == 1) { 26318c2ecf20Sopenharmony_ci /*0x29270*/ 26328c2ecf20Sopenharmony_ci reg = CN23XX_SLI_OUT_BP_EN2_W1S; 26338c2ecf20Sopenharmony_ci len += sprintf(s + len, 26348c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT_OUT_BP_EN2_W1S): %016llx\n", 26358c2ecf20Sopenharmony_ci reg, (u64)octeon_read_csr64(oct, reg)); 26368c2ecf20Sopenharmony_ci } 26378c2ecf20Sopenharmony_ci 26388c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) { 26398c2ecf20Sopenharmony_ci reg = CN23XX_SLI_OQ_BUFF_INFO_SIZE(i); 26408c2ecf20Sopenharmony_ci len += 26418c2ecf20Sopenharmony_ci sprintf(s + len, "\n[%08x] (SLI_PKT%d_OUT_SIZE): %016llx\n", 26428c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 26438c2ecf20Sopenharmony_ci } 26448c2ecf20Sopenharmony_ci 26458c2ecf20Sopenharmony_ci /*0x10040*/ 26468c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) { 26478c2ecf20Sopenharmony_ci reg = CN23XX_SLI_IQ_INSTR_COUNT64(i); 26488c2ecf20Sopenharmony_ci len += sprintf(s + len, 26498c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n", 26508c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 26518c2ecf20Sopenharmony_ci } 26528c2ecf20Sopenharmony_ci 26538c2ecf20Sopenharmony_ci /*0x10080*/ 26548c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) { 26558c2ecf20Sopenharmony_ci reg = CN23XX_SLI_OQ_PKTS_CREDIT(i); 26568c2ecf20Sopenharmony_ci len += sprintf(s + len, 26578c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016llx\n", 26588c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 26598c2ecf20Sopenharmony_ci } 26608c2ecf20Sopenharmony_ci 26618c2ecf20Sopenharmony_ci /*0x10090*/ 26628c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) { 26638c2ecf20Sopenharmony_ci reg = CN23XX_SLI_OQ_SIZE(i); 26648c2ecf20Sopenharmony_ci len += sprintf( 26658c2ecf20Sopenharmony_ci s + len, "\n[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016llx\n", 26668c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 26678c2ecf20Sopenharmony_ci } 26688c2ecf20Sopenharmony_ci 26698c2ecf20Sopenharmony_ci /*0x10050*/ 26708c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) { 26718c2ecf20Sopenharmony_ci reg = CN23XX_SLI_OQ_PKT_CONTROL(i); 26728c2ecf20Sopenharmony_ci len += sprintf( 26738c2ecf20Sopenharmony_ci s + len, 26748c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016llx\n", 26758c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 26768c2ecf20Sopenharmony_ci } 26778c2ecf20Sopenharmony_ci 26788c2ecf20Sopenharmony_ci /*0x10070*/ 26798c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) { 26808c2ecf20Sopenharmony_ci reg = CN23XX_SLI_OQ_BASE_ADDR64(i); 26818c2ecf20Sopenharmony_ci len += sprintf(s + len, 26828c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_SLIST_BADDR): %016llx\n", 26838c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 26848c2ecf20Sopenharmony_ci } 26858c2ecf20Sopenharmony_ci 26868c2ecf20Sopenharmony_ci /*0x100a0*/ 26878c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) { 26888c2ecf20Sopenharmony_ci reg = CN23XX_SLI_OQ_PKT_INT_LEVELS(i); 26898c2ecf20Sopenharmony_ci len += sprintf(s + len, 26908c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_INT_LEVELS): %016llx\n", 26918c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 26928c2ecf20Sopenharmony_ci } 26938c2ecf20Sopenharmony_ci 26948c2ecf20Sopenharmony_ci /*0x100b0*/ 26958c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) { 26968c2ecf20Sopenharmony_ci reg = CN23XX_SLI_OQ_PKTS_SENT(i); 26978c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%08x] (SLI_PKT%d_CNTS): %016llx\n", 26988c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 26998c2ecf20Sopenharmony_ci } 27008c2ecf20Sopenharmony_ci 27018c2ecf20Sopenharmony_ci /*0x100c0*/ 27028c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) { 27038c2ecf20Sopenharmony_ci reg = 0x100c0 + i * CN23XX_OQ_OFFSET; 27048c2ecf20Sopenharmony_ci len += sprintf(s + len, 27058c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_ERROR_INFO): %016llx\n", 27068c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 27078c2ecf20Sopenharmony_ci 27088c2ecf20Sopenharmony_ci /*0x10000*/ 27098c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) { 27108c2ecf20Sopenharmony_ci reg = CN23XX_SLI_IQ_PKT_CONTROL64(i); 27118c2ecf20Sopenharmony_ci len += sprintf( 27128c2ecf20Sopenharmony_ci s + len, 27138c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_INPUT_CONTROL): %016llx\n", 27148c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 27158c2ecf20Sopenharmony_ci } 27168c2ecf20Sopenharmony_ci 27178c2ecf20Sopenharmony_ci /*0x10010*/ 27188c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) { 27198c2ecf20Sopenharmony_ci reg = CN23XX_SLI_IQ_BASE_ADDR64(i); 27208c2ecf20Sopenharmony_ci len += sprintf( 27218c2ecf20Sopenharmony_ci s + len, 27228c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_INSTR_BADDR): %016llx\n", reg, 27238c2ecf20Sopenharmony_ci i, (u64)octeon_read_csr64(oct, reg)); 27248c2ecf20Sopenharmony_ci } 27258c2ecf20Sopenharmony_ci 27268c2ecf20Sopenharmony_ci /*0x10020*/ 27278c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) { 27288c2ecf20Sopenharmony_ci reg = CN23XX_SLI_IQ_DOORBELL(i); 27298c2ecf20Sopenharmony_ci len += sprintf( 27308c2ecf20Sopenharmony_ci s + len, 27318c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016llx\n", 27328c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 27338c2ecf20Sopenharmony_ci } 27348c2ecf20Sopenharmony_ci 27358c2ecf20Sopenharmony_ci /*0x10030*/ 27368c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) { 27378c2ecf20Sopenharmony_ci reg = CN23XX_SLI_IQ_SIZE(i); 27388c2ecf20Sopenharmony_ci len += sprintf( 27398c2ecf20Sopenharmony_ci s + len, 27408c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016llx\n", 27418c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 27428c2ecf20Sopenharmony_ci } 27438c2ecf20Sopenharmony_ci 27448c2ecf20Sopenharmony_ci /*0x10040*/ 27458c2ecf20Sopenharmony_ci for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) 27468c2ecf20Sopenharmony_ci reg = CN23XX_SLI_IQ_INSTR_COUNT64(i); 27478c2ecf20Sopenharmony_ci len += sprintf(s + len, 27488c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n", 27498c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 27508c2ecf20Sopenharmony_ci } 27518c2ecf20Sopenharmony_ci 27528c2ecf20Sopenharmony_ci return len; 27538c2ecf20Sopenharmony_ci} 27548c2ecf20Sopenharmony_ci 27558c2ecf20Sopenharmony_cistatic int cn23xx_vf_read_csr_reg(char *s, struct octeon_device *oct) 27568c2ecf20Sopenharmony_ci{ 27578c2ecf20Sopenharmony_ci int len = 0; 27588c2ecf20Sopenharmony_ci u32 reg; 27598c2ecf20Sopenharmony_ci int i; 27608c2ecf20Sopenharmony_ci 27618c2ecf20Sopenharmony_ci /* PCI Window Registers */ 27628c2ecf20Sopenharmony_ci 27638c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n"); 27648c2ecf20Sopenharmony_ci 27658c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 27668c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_OQ_BUFF_INFO_SIZE(i); 27678c2ecf20Sopenharmony_ci len += sprintf(s + len, 27688c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_OUT_SIZE): %016llx\n", 27698c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 27708c2ecf20Sopenharmony_ci } 27718c2ecf20Sopenharmony_ci 27728c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 27738c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_IQ_INSTR_COUNT64(i); 27748c2ecf20Sopenharmony_ci len += sprintf(s + len, 27758c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n", 27768c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 27778c2ecf20Sopenharmony_ci } 27788c2ecf20Sopenharmony_ci 27798c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 27808c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_OQ_PKTS_CREDIT(i); 27818c2ecf20Sopenharmony_ci len += sprintf(s + len, 27828c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016llx\n", 27838c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 27848c2ecf20Sopenharmony_ci } 27858c2ecf20Sopenharmony_ci 27868c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 27878c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_OQ_SIZE(i); 27888c2ecf20Sopenharmony_ci len += sprintf(s + len, 27898c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016llx\n", 27908c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 27918c2ecf20Sopenharmony_ci } 27928c2ecf20Sopenharmony_ci 27938c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 27948c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_OQ_PKT_CONTROL(i); 27958c2ecf20Sopenharmony_ci len += sprintf(s + len, 27968c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016llx\n", 27978c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 27988c2ecf20Sopenharmony_ci } 27998c2ecf20Sopenharmony_ci 28008c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 28018c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_OQ_BASE_ADDR64(i); 28028c2ecf20Sopenharmony_ci len += sprintf(s + len, 28038c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_SLIST_BADDR): %016llx\n", 28048c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 28058c2ecf20Sopenharmony_ci } 28068c2ecf20Sopenharmony_ci 28078c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 28088c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(i); 28098c2ecf20Sopenharmony_ci len += sprintf(s + len, 28108c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_INT_LEVELS): %016llx\n", 28118c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 28128c2ecf20Sopenharmony_ci } 28138c2ecf20Sopenharmony_ci 28148c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 28158c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_OQ_PKTS_SENT(i); 28168c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%08x] (SLI_PKT%d_CNTS): %016llx\n", 28178c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 28188c2ecf20Sopenharmony_ci } 28198c2ecf20Sopenharmony_ci 28208c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 28218c2ecf20Sopenharmony_ci reg = 0x100c0 + i * CN23XX_VF_OQ_OFFSET; 28228c2ecf20Sopenharmony_ci len += sprintf(s + len, 28238c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_ERROR_INFO): %016llx\n", 28248c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 28258c2ecf20Sopenharmony_ci } 28268c2ecf20Sopenharmony_ci 28278c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 28288c2ecf20Sopenharmony_ci reg = 0x100d0 + i * CN23XX_VF_IQ_OFFSET; 28298c2ecf20Sopenharmony_ci len += sprintf(s + len, 28308c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_VF_INT_SUM): %016llx\n", 28318c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 28328c2ecf20Sopenharmony_ci } 28338c2ecf20Sopenharmony_ci 28348c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 28358c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_IQ_PKT_CONTROL64(i); 28368c2ecf20Sopenharmony_ci len += sprintf(s + len, 28378c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_INPUT_CONTROL): %016llx\n", 28388c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 28398c2ecf20Sopenharmony_ci } 28408c2ecf20Sopenharmony_ci 28418c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 28428c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_IQ_BASE_ADDR64(i); 28438c2ecf20Sopenharmony_ci len += sprintf(s + len, 28448c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_INSTR_BADDR): %016llx\n", 28458c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 28468c2ecf20Sopenharmony_ci } 28478c2ecf20Sopenharmony_ci 28488c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 28498c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_IQ_DOORBELL(i); 28508c2ecf20Sopenharmony_ci len += sprintf(s + len, 28518c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016llx\n", 28528c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 28538c2ecf20Sopenharmony_ci } 28548c2ecf20Sopenharmony_ci 28558c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 28568c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_IQ_SIZE(i); 28578c2ecf20Sopenharmony_ci len += sprintf(s + len, 28588c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016llx\n", 28598c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 28608c2ecf20Sopenharmony_ci } 28618c2ecf20Sopenharmony_ci 28628c2ecf20Sopenharmony_ci for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) { 28638c2ecf20Sopenharmony_ci reg = CN23XX_VF_SLI_IQ_INSTR_COUNT64(i); 28648c2ecf20Sopenharmony_ci len += sprintf(s + len, 28658c2ecf20Sopenharmony_ci "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n", 28668c2ecf20Sopenharmony_ci reg, i, (u64)octeon_read_csr64(oct, reg)); 28678c2ecf20Sopenharmony_ci } 28688c2ecf20Sopenharmony_ci 28698c2ecf20Sopenharmony_ci return len; 28708c2ecf20Sopenharmony_ci} 28718c2ecf20Sopenharmony_ci 28728c2ecf20Sopenharmony_cistatic int cn6xxx_read_csr_reg(char *s, struct octeon_device *oct) 28738c2ecf20Sopenharmony_ci{ 28748c2ecf20Sopenharmony_ci u32 reg; 28758c2ecf20Sopenharmony_ci int i, len = 0; 28768c2ecf20Sopenharmony_ci 28778c2ecf20Sopenharmony_ci /* PCI Window Registers */ 28788c2ecf20Sopenharmony_ci 28798c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n"); 28808c2ecf20Sopenharmony_ci reg = CN6XXX_WIN_WR_ADDR_LO; 28818c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%02x] (WIN_WR_ADDR_LO): %08x\n", 28828c2ecf20Sopenharmony_ci CN6XXX_WIN_WR_ADDR_LO, octeon_read_csr(oct, reg)); 28838c2ecf20Sopenharmony_ci reg = CN6XXX_WIN_WR_ADDR_HI; 28848c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%02x] (WIN_WR_ADDR_HI): %08x\n", 28858c2ecf20Sopenharmony_ci CN6XXX_WIN_WR_ADDR_HI, octeon_read_csr(oct, reg)); 28868c2ecf20Sopenharmony_ci reg = CN6XXX_WIN_RD_ADDR_LO; 28878c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%02x] (WIN_RD_ADDR_LO): %08x\n", 28888c2ecf20Sopenharmony_ci CN6XXX_WIN_RD_ADDR_LO, octeon_read_csr(oct, reg)); 28898c2ecf20Sopenharmony_ci reg = CN6XXX_WIN_RD_ADDR_HI; 28908c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%02x] (WIN_RD_ADDR_HI): %08x\n", 28918c2ecf20Sopenharmony_ci CN6XXX_WIN_RD_ADDR_HI, octeon_read_csr(oct, reg)); 28928c2ecf20Sopenharmony_ci reg = CN6XXX_WIN_WR_DATA_LO; 28938c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%02x] (WIN_WR_DATA_LO): %08x\n", 28948c2ecf20Sopenharmony_ci CN6XXX_WIN_WR_DATA_LO, octeon_read_csr(oct, reg)); 28958c2ecf20Sopenharmony_ci reg = CN6XXX_WIN_WR_DATA_HI; 28968c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%02x] (WIN_WR_DATA_HI): %08x\n", 28978c2ecf20Sopenharmony_ci CN6XXX_WIN_WR_DATA_HI, octeon_read_csr(oct, reg)); 28988c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%02x] (WIN_WR_MASK_REG): %08x\n", 28998c2ecf20Sopenharmony_ci CN6XXX_WIN_WR_MASK_REG, 29008c2ecf20Sopenharmony_ci octeon_read_csr(oct, CN6XXX_WIN_WR_MASK_REG)); 29018c2ecf20Sopenharmony_ci 29028c2ecf20Sopenharmony_ci /* PCI Interrupt Register */ 29038c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%x] (INT_ENABLE PORT 0): %08x\n", 29048c2ecf20Sopenharmony_ci CN6XXX_SLI_INT_ENB64_PORT0, octeon_read_csr(oct, 29058c2ecf20Sopenharmony_ci CN6XXX_SLI_INT_ENB64_PORT0)); 29068c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%x] (INT_ENABLE PORT 1): %08x\n", 29078c2ecf20Sopenharmony_ci CN6XXX_SLI_INT_ENB64_PORT1, 29088c2ecf20Sopenharmony_ci octeon_read_csr(oct, CN6XXX_SLI_INT_ENB64_PORT1)); 29098c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%x] (INT_SUM): %08x\n", CN6XXX_SLI_INT_SUM64, 29108c2ecf20Sopenharmony_ci octeon_read_csr(oct, CN6XXX_SLI_INT_SUM64)); 29118c2ecf20Sopenharmony_ci 29128c2ecf20Sopenharmony_ci /* PCI Output queue registers */ 29138c2ecf20Sopenharmony_ci for (i = 0; i < oct->num_oqs; i++) { 29148c2ecf20Sopenharmony_ci reg = CN6XXX_SLI_OQ_PKTS_SENT(i); 29158c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%x] (PKTS_SENT_%d): %08x\n", 29168c2ecf20Sopenharmony_ci reg, i, octeon_read_csr(oct, reg)); 29178c2ecf20Sopenharmony_ci reg = CN6XXX_SLI_OQ_PKTS_CREDIT(i); 29188c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%x] (PKT_CREDITS_%d): %08x\n", 29198c2ecf20Sopenharmony_ci reg, i, octeon_read_csr(oct, reg)); 29208c2ecf20Sopenharmony_ci } 29218c2ecf20Sopenharmony_ci reg = CN6XXX_SLI_OQ_INT_LEVEL_PKTS; 29228c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%x] (PKTS_SENT_INT_LEVEL): %08x\n", 29238c2ecf20Sopenharmony_ci reg, octeon_read_csr(oct, reg)); 29248c2ecf20Sopenharmony_ci reg = CN6XXX_SLI_OQ_INT_LEVEL_TIME; 29258c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%x] (PKTS_SENT_TIME): %08x\n", 29268c2ecf20Sopenharmony_ci reg, octeon_read_csr(oct, reg)); 29278c2ecf20Sopenharmony_ci 29288c2ecf20Sopenharmony_ci /* PCI Input queue registers */ 29298c2ecf20Sopenharmony_ci for (i = 0; i <= 3; i++) { 29308c2ecf20Sopenharmony_ci u32 reg; 29318c2ecf20Sopenharmony_ci 29328c2ecf20Sopenharmony_ci reg = CN6XXX_SLI_IQ_DOORBELL(i); 29338c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%x] (INSTR_DOORBELL_%d): %08x\n", 29348c2ecf20Sopenharmony_ci reg, i, octeon_read_csr(oct, reg)); 29358c2ecf20Sopenharmony_ci reg = CN6XXX_SLI_IQ_INSTR_COUNT(i); 29368c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%x] (INSTR_COUNT_%d): %08x\n", 29378c2ecf20Sopenharmony_ci reg, i, octeon_read_csr(oct, reg)); 29388c2ecf20Sopenharmony_ci } 29398c2ecf20Sopenharmony_ci 29408c2ecf20Sopenharmony_ci /* PCI DMA registers */ 29418c2ecf20Sopenharmony_ci 29428c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%x] (DMA_CNT_0): %08x\n", 29438c2ecf20Sopenharmony_ci CN6XXX_DMA_CNT(0), 29448c2ecf20Sopenharmony_ci octeon_read_csr(oct, CN6XXX_DMA_CNT(0))); 29458c2ecf20Sopenharmony_ci reg = CN6XXX_DMA_PKT_INT_LEVEL(0); 29468c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%x] (DMA_INT_LEV_0): %08x\n", 29478c2ecf20Sopenharmony_ci CN6XXX_DMA_PKT_INT_LEVEL(0), octeon_read_csr(oct, reg)); 29488c2ecf20Sopenharmony_ci reg = CN6XXX_DMA_TIME_INT_LEVEL(0); 29498c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%x] (DMA_TIME_0): %08x\n", 29508c2ecf20Sopenharmony_ci CN6XXX_DMA_TIME_INT_LEVEL(0), 29518c2ecf20Sopenharmony_ci octeon_read_csr(oct, reg)); 29528c2ecf20Sopenharmony_ci 29538c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n[%x] (DMA_CNT_1): %08x\n", 29548c2ecf20Sopenharmony_ci CN6XXX_DMA_CNT(1), 29558c2ecf20Sopenharmony_ci octeon_read_csr(oct, CN6XXX_DMA_CNT(1))); 29568c2ecf20Sopenharmony_ci reg = CN6XXX_DMA_PKT_INT_LEVEL(1); 29578c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%x] (DMA_INT_LEV_1): %08x\n", 29588c2ecf20Sopenharmony_ci CN6XXX_DMA_PKT_INT_LEVEL(1), 29598c2ecf20Sopenharmony_ci octeon_read_csr(oct, reg)); 29608c2ecf20Sopenharmony_ci reg = CN6XXX_DMA_PKT_INT_LEVEL(1); 29618c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%x] (DMA_TIME_1): %08x\n", 29628c2ecf20Sopenharmony_ci CN6XXX_DMA_TIME_INT_LEVEL(1), 29638c2ecf20Sopenharmony_ci octeon_read_csr(oct, reg)); 29648c2ecf20Sopenharmony_ci 29658c2ecf20Sopenharmony_ci /* PCI Index registers */ 29668c2ecf20Sopenharmony_ci 29678c2ecf20Sopenharmony_ci len += sprintf(s + len, "\n"); 29688c2ecf20Sopenharmony_ci 29698c2ecf20Sopenharmony_ci for (i = 0; i < 16; i++) { 29708c2ecf20Sopenharmony_ci reg = lio_pci_readq(oct, CN6XXX_BAR1_REG(i, oct->pcie_port)); 29718c2ecf20Sopenharmony_ci len += sprintf(s + len, "[%llx] (BAR1_INDEX_%02d): %08x\n", 29728c2ecf20Sopenharmony_ci CN6XXX_BAR1_REG(i, oct->pcie_port), i, reg); 29738c2ecf20Sopenharmony_ci } 29748c2ecf20Sopenharmony_ci 29758c2ecf20Sopenharmony_ci return len; 29768c2ecf20Sopenharmony_ci} 29778c2ecf20Sopenharmony_ci 29788c2ecf20Sopenharmony_cistatic int cn6xxx_read_config_reg(char *s, struct octeon_device *oct) 29798c2ecf20Sopenharmony_ci{ 29808c2ecf20Sopenharmony_ci u32 val; 29818c2ecf20Sopenharmony_ci int i, len = 0; 29828c2ecf20Sopenharmony_ci 29838c2ecf20Sopenharmony_ci /* PCI CONFIG Registers */ 29848c2ecf20Sopenharmony_ci 29858c2ecf20Sopenharmony_ci len += sprintf(s + len, 29868c2ecf20Sopenharmony_ci "\n\t Octeon Config space Registers\n\n"); 29878c2ecf20Sopenharmony_ci 29888c2ecf20Sopenharmony_ci for (i = 0; i <= 13; i++) { 29898c2ecf20Sopenharmony_ci pci_read_config_dword(oct->pci_dev, (i * 4), &val); 29908c2ecf20Sopenharmony_ci len += sprintf(s + len, "[0x%x] (Config[%d]): 0x%08x\n", 29918c2ecf20Sopenharmony_ci (i * 4), i, val); 29928c2ecf20Sopenharmony_ci } 29938c2ecf20Sopenharmony_ci 29948c2ecf20Sopenharmony_ci for (i = 30; i <= 34; i++) { 29958c2ecf20Sopenharmony_ci pci_read_config_dword(oct->pci_dev, (i * 4), &val); 29968c2ecf20Sopenharmony_ci len += sprintf(s + len, "[0x%x] (Config[%d]): 0x%08x\n", 29978c2ecf20Sopenharmony_ci (i * 4), i, val); 29988c2ecf20Sopenharmony_ci } 29998c2ecf20Sopenharmony_ci 30008c2ecf20Sopenharmony_ci return len; 30018c2ecf20Sopenharmony_ci} 30028c2ecf20Sopenharmony_ci 30038c2ecf20Sopenharmony_ci/* Return register dump user app. */ 30048c2ecf20Sopenharmony_cistatic void lio_get_regs(struct net_device *dev, 30058c2ecf20Sopenharmony_ci struct ethtool_regs *regs, void *regbuf) 30068c2ecf20Sopenharmony_ci{ 30078c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(dev); 30088c2ecf20Sopenharmony_ci int len = 0; 30098c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 30108c2ecf20Sopenharmony_ci 30118c2ecf20Sopenharmony_ci regs->version = OCT_ETHTOOL_REGSVER; 30128c2ecf20Sopenharmony_ci 30138c2ecf20Sopenharmony_ci switch (oct->chip_id) { 30148c2ecf20Sopenharmony_ci case OCTEON_CN23XX_PF_VID: 30158c2ecf20Sopenharmony_ci memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN_23XX); 30168c2ecf20Sopenharmony_ci len += cn23xx_read_csr_reg(regbuf + len, oct); 30178c2ecf20Sopenharmony_ci break; 30188c2ecf20Sopenharmony_ci case OCTEON_CN23XX_VF_VID: 30198c2ecf20Sopenharmony_ci memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN_23XX_VF); 30208c2ecf20Sopenharmony_ci len += cn23xx_vf_read_csr_reg(regbuf + len, oct); 30218c2ecf20Sopenharmony_ci break; 30228c2ecf20Sopenharmony_ci case OCTEON_CN68XX: 30238c2ecf20Sopenharmony_ci case OCTEON_CN66XX: 30248c2ecf20Sopenharmony_ci memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN); 30258c2ecf20Sopenharmony_ci len += cn6xxx_read_csr_reg(regbuf + len, oct); 30268c2ecf20Sopenharmony_ci len += cn6xxx_read_config_reg(regbuf + len, oct); 30278c2ecf20Sopenharmony_ci break; 30288c2ecf20Sopenharmony_ci default: 30298c2ecf20Sopenharmony_ci dev_err(&oct->pci_dev->dev, "%s Unknown chipid: %d\n", 30308c2ecf20Sopenharmony_ci __func__, oct->chip_id); 30318c2ecf20Sopenharmony_ci } 30328c2ecf20Sopenharmony_ci} 30338c2ecf20Sopenharmony_ci 30348c2ecf20Sopenharmony_cistatic u32 lio_get_priv_flags(struct net_device *netdev) 30358c2ecf20Sopenharmony_ci{ 30368c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 30378c2ecf20Sopenharmony_ci 30388c2ecf20Sopenharmony_ci return lio->oct_dev->priv_flags; 30398c2ecf20Sopenharmony_ci} 30408c2ecf20Sopenharmony_ci 30418c2ecf20Sopenharmony_cistatic int lio_set_priv_flags(struct net_device *netdev, u32 flags) 30428c2ecf20Sopenharmony_ci{ 30438c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 30448c2ecf20Sopenharmony_ci bool intr_by_tx_bytes = !!(flags & (0x1 << OCT_PRIV_FLAG_TX_BYTES)); 30458c2ecf20Sopenharmony_ci 30468c2ecf20Sopenharmony_ci lio_set_priv_flag(lio->oct_dev, OCT_PRIV_FLAG_TX_BYTES, 30478c2ecf20Sopenharmony_ci intr_by_tx_bytes); 30488c2ecf20Sopenharmony_ci return 0; 30498c2ecf20Sopenharmony_ci} 30508c2ecf20Sopenharmony_ci 30518c2ecf20Sopenharmony_cistatic int lio_get_fecparam(struct net_device *netdev, 30528c2ecf20Sopenharmony_ci struct ethtool_fecparam *fec) 30538c2ecf20Sopenharmony_ci{ 30548c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 30558c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 30568c2ecf20Sopenharmony_ci 30578c2ecf20Sopenharmony_ci fec->active_fec = ETHTOOL_FEC_NONE; 30588c2ecf20Sopenharmony_ci fec->fec = ETHTOOL_FEC_NONE; 30598c2ecf20Sopenharmony_ci 30608c2ecf20Sopenharmony_ci if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID || 30618c2ecf20Sopenharmony_ci oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) { 30628c2ecf20Sopenharmony_ci if (oct->no_speed_setting == 1) 30638c2ecf20Sopenharmony_ci return 0; 30648c2ecf20Sopenharmony_ci 30658c2ecf20Sopenharmony_ci liquidio_get_fec(lio); 30668c2ecf20Sopenharmony_ci fec->fec = (ETHTOOL_FEC_RS | ETHTOOL_FEC_OFF); 30678c2ecf20Sopenharmony_ci if (oct->props[lio->ifidx].fec == 1) 30688c2ecf20Sopenharmony_ci fec->active_fec = ETHTOOL_FEC_RS; 30698c2ecf20Sopenharmony_ci else 30708c2ecf20Sopenharmony_ci fec->active_fec = ETHTOOL_FEC_OFF; 30718c2ecf20Sopenharmony_ci } 30728c2ecf20Sopenharmony_ci 30738c2ecf20Sopenharmony_ci return 0; 30748c2ecf20Sopenharmony_ci} 30758c2ecf20Sopenharmony_ci 30768c2ecf20Sopenharmony_cistatic int lio_set_fecparam(struct net_device *netdev, 30778c2ecf20Sopenharmony_ci struct ethtool_fecparam *fec) 30788c2ecf20Sopenharmony_ci{ 30798c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 30808c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 30818c2ecf20Sopenharmony_ci 30828c2ecf20Sopenharmony_ci if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID || 30838c2ecf20Sopenharmony_ci oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) { 30848c2ecf20Sopenharmony_ci if (oct->no_speed_setting == 1) 30858c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 30868c2ecf20Sopenharmony_ci 30878c2ecf20Sopenharmony_ci if (fec->fec & ETHTOOL_FEC_OFF) 30888c2ecf20Sopenharmony_ci liquidio_set_fec(lio, 0); 30898c2ecf20Sopenharmony_ci else if (fec->fec & ETHTOOL_FEC_RS) 30908c2ecf20Sopenharmony_ci liquidio_set_fec(lio, 1); 30918c2ecf20Sopenharmony_ci else 30928c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 30938c2ecf20Sopenharmony_ci } else { 30948c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 30958c2ecf20Sopenharmony_ci } 30968c2ecf20Sopenharmony_ci 30978c2ecf20Sopenharmony_ci return 0; 30988c2ecf20Sopenharmony_ci} 30998c2ecf20Sopenharmony_ci 31008c2ecf20Sopenharmony_ci#define LIO_ETHTOOL_COALESCE (ETHTOOL_COALESCE_RX_USECS | \ 31018c2ecf20Sopenharmony_ci ETHTOOL_COALESCE_MAX_FRAMES | \ 31028c2ecf20Sopenharmony_ci ETHTOOL_COALESCE_USE_ADAPTIVE | \ 31038c2ecf20Sopenharmony_ci ETHTOOL_COALESCE_RX_MAX_FRAMES_LOW | \ 31048c2ecf20Sopenharmony_ci ETHTOOL_COALESCE_TX_MAX_FRAMES_LOW | \ 31058c2ecf20Sopenharmony_ci ETHTOOL_COALESCE_RX_MAX_FRAMES_HIGH | \ 31068c2ecf20Sopenharmony_ci ETHTOOL_COALESCE_TX_MAX_FRAMES_HIGH | \ 31078c2ecf20Sopenharmony_ci ETHTOOL_COALESCE_PKT_RATE_RX_USECS) 31088c2ecf20Sopenharmony_ci 31098c2ecf20Sopenharmony_cistatic const struct ethtool_ops lio_ethtool_ops = { 31108c2ecf20Sopenharmony_ci .supported_coalesce_params = LIO_ETHTOOL_COALESCE, 31118c2ecf20Sopenharmony_ci .get_link_ksettings = lio_get_link_ksettings, 31128c2ecf20Sopenharmony_ci .set_link_ksettings = lio_set_link_ksettings, 31138c2ecf20Sopenharmony_ci .get_fecparam = lio_get_fecparam, 31148c2ecf20Sopenharmony_ci .set_fecparam = lio_set_fecparam, 31158c2ecf20Sopenharmony_ci .get_link = ethtool_op_get_link, 31168c2ecf20Sopenharmony_ci .get_drvinfo = lio_get_drvinfo, 31178c2ecf20Sopenharmony_ci .get_ringparam = lio_ethtool_get_ringparam, 31188c2ecf20Sopenharmony_ci .set_ringparam = lio_ethtool_set_ringparam, 31198c2ecf20Sopenharmony_ci .get_channels = lio_ethtool_get_channels, 31208c2ecf20Sopenharmony_ci .set_channels = lio_ethtool_set_channels, 31218c2ecf20Sopenharmony_ci .set_phys_id = lio_set_phys_id, 31228c2ecf20Sopenharmony_ci .get_eeprom_len = lio_get_eeprom_len, 31238c2ecf20Sopenharmony_ci .get_eeprom = lio_get_eeprom, 31248c2ecf20Sopenharmony_ci .get_strings = lio_get_strings, 31258c2ecf20Sopenharmony_ci .get_ethtool_stats = lio_get_ethtool_stats, 31268c2ecf20Sopenharmony_ci .get_pauseparam = lio_get_pauseparam, 31278c2ecf20Sopenharmony_ci .set_pauseparam = lio_set_pauseparam, 31288c2ecf20Sopenharmony_ci .get_regs_len = lio_get_regs_len, 31298c2ecf20Sopenharmony_ci .get_regs = lio_get_regs, 31308c2ecf20Sopenharmony_ci .get_msglevel = lio_get_msglevel, 31318c2ecf20Sopenharmony_ci .set_msglevel = lio_set_msglevel, 31328c2ecf20Sopenharmony_ci .get_sset_count = lio_get_sset_count, 31338c2ecf20Sopenharmony_ci .get_coalesce = lio_get_intr_coalesce, 31348c2ecf20Sopenharmony_ci .set_coalesce = lio_set_intr_coalesce, 31358c2ecf20Sopenharmony_ci .get_priv_flags = lio_get_priv_flags, 31368c2ecf20Sopenharmony_ci .set_priv_flags = lio_set_priv_flags, 31378c2ecf20Sopenharmony_ci .get_ts_info = lio_get_ts_info, 31388c2ecf20Sopenharmony_ci}; 31398c2ecf20Sopenharmony_ci 31408c2ecf20Sopenharmony_cistatic const struct ethtool_ops lio_vf_ethtool_ops = { 31418c2ecf20Sopenharmony_ci .supported_coalesce_params = LIO_ETHTOOL_COALESCE, 31428c2ecf20Sopenharmony_ci .get_link_ksettings = lio_get_link_ksettings, 31438c2ecf20Sopenharmony_ci .get_link = ethtool_op_get_link, 31448c2ecf20Sopenharmony_ci .get_drvinfo = lio_get_vf_drvinfo, 31458c2ecf20Sopenharmony_ci .get_ringparam = lio_ethtool_get_ringparam, 31468c2ecf20Sopenharmony_ci .set_ringparam = lio_ethtool_set_ringparam, 31478c2ecf20Sopenharmony_ci .get_channels = lio_ethtool_get_channels, 31488c2ecf20Sopenharmony_ci .set_channels = lio_ethtool_set_channels, 31498c2ecf20Sopenharmony_ci .get_strings = lio_vf_get_strings, 31508c2ecf20Sopenharmony_ci .get_ethtool_stats = lio_vf_get_ethtool_stats, 31518c2ecf20Sopenharmony_ci .get_regs_len = lio_get_regs_len, 31528c2ecf20Sopenharmony_ci .get_regs = lio_get_regs, 31538c2ecf20Sopenharmony_ci .get_msglevel = lio_get_msglevel, 31548c2ecf20Sopenharmony_ci .set_msglevel = lio_vf_set_msglevel, 31558c2ecf20Sopenharmony_ci .get_sset_count = lio_vf_get_sset_count, 31568c2ecf20Sopenharmony_ci .get_coalesce = lio_get_intr_coalesce, 31578c2ecf20Sopenharmony_ci .set_coalesce = lio_set_intr_coalesce, 31588c2ecf20Sopenharmony_ci .get_priv_flags = lio_get_priv_flags, 31598c2ecf20Sopenharmony_ci .set_priv_flags = lio_set_priv_flags, 31608c2ecf20Sopenharmony_ci .get_ts_info = lio_get_ts_info, 31618c2ecf20Sopenharmony_ci}; 31628c2ecf20Sopenharmony_ci 31638c2ecf20Sopenharmony_civoid liquidio_set_ethtool_ops(struct net_device *netdev) 31648c2ecf20Sopenharmony_ci{ 31658c2ecf20Sopenharmony_ci struct lio *lio = GET_LIO(netdev); 31668c2ecf20Sopenharmony_ci struct octeon_device *oct = lio->oct_dev; 31678c2ecf20Sopenharmony_ci 31688c2ecf20Sopenharmony_ci if (OCTEON_CN23XX_VF(oct)) 31698c2ecf20Sopenharmony_ci netdev->ethtool_ops = &lio_vf_ethtool_ops; 31708c2ecf20Sopenharmony_ci else 31718c2ecf20Sopenharmony_ci netdev->ethtool_ops = &lio_ethtool_ops; 31728c2ecf20Sopenharmony_ci} 3173