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