xref: /openbmc/linux/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
1f21fb3edSRaghu Vatsavayi /**********************************************************************
2f21fb3edSRaghu Vatsavayi  * Author: Cavium, Inc.
3f21fb3edSRaghu Vatsavayi  *
4f21fb3edSRaghu Vatsavayi  * Contact: support@cavium.com
5f21fb3edSRaghu Vatsavayi  *          Please include "LiquidIO" in the subject.
6f21fb3edSRaghu Vatsavayi  *
750579d3dSRaghu Vatsavayi  * Copyright (c) 2003-2016 Cavium, Inc.
8f21fb3edSRaghu Vatsavayi  *
9f21fb3edSRaghu Vatsavayi  * This file is free software; you can redistribute it and/or modify
10f21fb3edSRaghu Vatsavayi  * it under the terms of the GNU General Public License, Version 2, as
11f21fb3edSRaghu Vatsavayi  * published by the Free Software Foundation.
12f21fb3edSRaghu Vatsavayi  *
13f21fb3edSRaghu Vatsavayi  * This file is distributed in the hope that it will be useful, but
14f21fb3edSRaghu Vatsavayi  * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15f21fb3edSRaghu Vatsavayi  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
1650579d3dSRaghu Vatsavayi  * NONINFRINGEMENT.  See the GNU General Public License for more details.
1750579d3dSRaghu Vatsavayi  ***********************************************************************/
18cc69837fSJakub Kicinski #include <linux/ethtool.h>
19f21fb3edSRaghu Vatsavayi #include <linux/netdevice.h>
20f21fb3edSRaghu Vatsavayi #include <linux/net_tstamp.h>
21f21fb3edSRaghu Vatsavayi #include <linux/pci.h>
22f21fb3edSRaghu Vatsavayi #include "liquidio_common.h"
23f21fb3edSRaghu Vatsavayi #include "octeon_droq.h"
24f21fb3edSRaghu Vatsavayi #include "octeon_iq.h"
25f21fb3edSRaghu Vatsavayi #include "response_manager.h"
26f21fb3edSRaghu Vatsavayi #include "octeon_device.h"
27f21fb3edSRaghu Vatsavayi #include "octeon_nic.h"
28f21fb3edSRaghu Vatsavayi #include "octeon_main.h"
29f21fb3edSRaghu Vatsavayi #include "octeon_network.h"
30f21fb3edSRaghu Vatsavayi #include "cn66xx_regs.h"
31f21fb3edSRaghu Vatsavayi #include "cn66xx_device.h"
32dc3abcbeSRaghu Vatsavayi #include "cn23xx_pf_device.h"
33d8ab848cSRaghu Vatsavayi #include "cn23xx_vf_device.h"
34f21fb3edSRaghu Vatsavayi 
35a82457f1SIntiyaz Basha static int lio_reset_queues(struct net_device *netdev, uint32_t num_qs);
361f164717SRaghu Vatsavayi 
3750c0add5SPrasad Kanneganti struct oct_intrmod_resp {
3850c0add5SPrasad Kanneganti 	u64     rh;
3950c0add5SPrasad Kanneganti 	struct oct_intrmod_cfg intrmod;
4050c0add5SPrasad Kanneganti 	u64     status;
4150c0add5SPrasad Kanneganti };
4250c0add5SPrasad Kanneganti 
43f21fb3edSRaghu Vatsavayi struct oct_mdio_cmd_resp {
44f21fb3edSRaghu Vatsavayi 	u64 rh;
45f21fb3edSRaghu Vatsavayi 	struct oct_mdio_cmd resp;
46f21fb3edSRaghu Vatsavayi 	u64 status;
47f21fb3edSRaghu Vatsavayi };
48f21fb3edSRaghu Vatsavayi 
49f21fb3edSRaghu Vatsavayi #define OCT_MDIO45_RESP_SIZE   (sizeof(struct oct_mdio_cmd_resp))
50f21fb3edSRaghu Vatsavayi 
51f21fb3edSRaghu Vatsavayi /* Octeon's interface mode of operation */
52f21fb3edSRaghu Vatsavayi enum {
53f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_DISABLED,
54f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_RGMII,
55f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_GMII,
56f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_SPI,
57f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_PCIE,
58f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_XAUI,
59f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_SGMII,
60f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_PICMG,
61f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_NPI,
62f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_LOOP,
63f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_SRIO,
64f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_ILK,
65f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_RXAUI,
66f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_QSGMII,
67f21fb3edSRaghu Vatsavayi 	INTERFACE_MODE_AGL,
689eb60844SRaghu Vatsavayi 	INTERFACE_MODE_XLAUI,
699eb60844SRaghu Vatsavayi 	INTERFACE_MODE_XFI,
709eb60844SRaghu Vatsavayi 	INTERFACE_MODE_10G_KR,
719eb60844SRaghu Vatsavayi 	INTERFACE_MODE_40G_KR4,
729eb60844SRaghu Vatsavayi 	INTERFACE_MODE_MIXED,
73f21fb3edSRaghu Vatsavayi };
74f21fb3edSRaghu Vatsavayi 
75f21fb3edSRaghu Vatsavayi #define OCT_ETHTOOL_REGDUMP_LEN  4096
76dc3abcbeSRaghu Vatsavayi #define OCT_ETHTOOL_REGDUMP_LEN_23XX  (4096 * 11)
77d8ab848cSRaghu Vatsavayi #define OCT_ETHTOOL_REGDUMP_LEN_23XX_VF  (4096 * 2)
78f21fb3edSRaghu Vatsavayi #define OCT_ETHTOOL_REGSVER  1
79f21fb3edSRaghu Vatsavayi 
801f164717SRaghu Vatsavayi /* statistics of PF */
811f164717SRaghu Vatsavayi static const char oct_stats_strings[][ETH_GSTRING_LEN] = {
821f164717SRaghu Vatsavayi 	"rx_packets",
831f164717SRaghu Vatsavayi 	"tx_packets",
841f164717SRaghu Vatsavayi 	"rx_bytes",
851f164717SRaghu Vatsavayi 	"tx_bytes",
86897ddc24SIntiyaz Basha 	"rx_errors",
87897ddc24SIntiyaz Basha 	"tx_errors",
88897ddc24SIntiyaz Basha 	"rx_dropped",
891f164717SRaghu Vatsavayi 	"tx_dropped",
901f164717SRaghu Vatsavayi 
911f164717SRaghu Vatsavayi 	"tx_total_sent",
921f164717SRaghu Vatsavayi 	"tx_total_fwd",
931f164717SRaghu Vatsavayi 	"tx_err_pko",
94741912c5SRick Farrington 	"tx_err_pki",
951f164717SRaghu Vatsavayi 	"tx_err_link",
961f164717SRaghu Vatsavayi 	"tx_err_drop",
971f164717SRaghu Vatsavayi 
981f164717SRaghu Vatsavayi 	"tx_tso",
991f164717SRaghu Vatsavayi 	"tx_tso_packets",
1001f164717SRaghu Vatsavayi 	"tx_tso_err",
10101fb237aSRaghu Vatsavayi 	"tx_vxlan",
1021f164717SRaghu Vatsavayi 
10380002347SPradeep Nalla 	"tx_mcast",
10480002347SPradeep Nalla 	"tx_bcast",
10580002347SPradeep Nalla 
1061f164717SRaghu Vatsavayi 	"mac_tx_total_pkts",
1071f164717SRaghu Vatsavayi 	"mac_tx_total_bytes",
1081f164717SRaghu Vatsavayi 	"mac_tx_mcast_pkts",
1091f164717SRaghu Vatsavayi 	"mac_tx_bcast_pkts",
110897ddc24SIntiyaz Basha 	"mac_tx_ctl_packets",
1111f164717SRaghu Vatsavayi 	"mac_tx_total_collisions",
1121f164717SRaghu Vatsavayi 	"mac_tx_one_collision",
11376c2a96dSColin Ian King 	"mac_tx_multi_collision",
1141f164717SRaghu Vatsavayi 	"mac_tx_max_collision_fail",
11556e0e295SColin Ian King 	"mac_tx_max_deferral_fail",
1161f164717SRaghu Vatsavayi 	"mac_tx_fifo_err",
1171f164717SRaghu Vatsavayi 	"mac_tx_runts",
1181f164717SRaghu Vatsavayi 
1191f164717SRaghu Vatsavayi 	"rx_total_rcvd",
1201f164717SRaghu Vatsavayi 	"rx_total_fwd",
12180002347SPradeep Nalla 	"rx_mcast",
12280002347SPradeep Nalla 	"rx_bcast",
1231f164717SRaghu Vatsavayi 	"rx_jabber_err",
1241f164717SRaghu Vatsavayi 	"rx_l2_err",
1251f164717SRaghu Vatsavayi 	"rx_frame_err",
1261f164717SRaghu Vatsavayi 	"rx_err_pko",
1271f164717SRaghu Vatsavayi 	"rx_err_link",
1281f164717SRaghu Vatsavayi 	"rx_err_drop",
1291f164717SRaghu Vatsavayi 
13001fb237aSRaghu Vatsavayi 	"rx_vxlan",
13101fb237aSRaghu Vatsavayi 	"rx_vxlan_err",
13201fb237aSRaghu Vatsavayi 
1331f164717SRaghu Vatsavayi 	"rx_lro_pkts",
1341f164717SRaghu Vatsavayi 	"rx_lro_bytes",
1351f164717SRaghu Vatsavayi 	"rx_total_lro",
1361f164717SRaghu Vatsavayi 
1371f164717SRaghu Vatsavayi 	"rx_lro_aborts",
1381f164717SRaghu Vatsavayi 	"rx_lro_aborts_port",
1391f164717SRaghu Vatsavayi 	"rx_lro_aborts_seq",
1401f164717SRaghu Vatsavayi 	"rx_lro_aborts_tsval",
1411f164717SRaghu Vatsavayi 	"rx_lro_aborts_timer",
1421f164717SRaghu Vatsavayi 	"rx_fwd_rate",
1431f164717SRaghu Vatsavayi 
1441f164717SRaghu Vatsavayi 	"mac_rx_total_rcvd",
1451f164717SRaghu Vatsavayi 	"mac_rx_bytes",
1461f164717SRaghu Vatsavayi 	"mac_rx_total_bcst",
1471f164717SRaghu Vatsavayi 	"mac_rx_total_mcst",
1481f164717SRaghu Vatsavayi 	"mac_rx_runts",
1491f164717SRaghu Vatsavayi 	"mac_rx_ctl_packets",
1501f164717SRaghu Vatsavayi 	"mac_rx_fifo_err",
1511f164717SRaghu Vatsavayi 	"mac_rx_dma_drop",
1521f164717SRaghu Vatsavayi 	"mac_rx_fcs_err",
1531f164717SRaghu Vatsavayi 
1541f164717SRaghu Vatsavayi 	"link_state_changes",
155f21fb3edSRaghu Vatsavayi };
156f21fb3edSRaghu Vatsavayi 
157d8ab848cSRaghu Vatsavayi /* statistics of VF */
158d8ab848cSRaghu Vatsavayi static const char oct_vf_stats_strings[][ETH_GSTRING_LEN] = {
159d8ab848cSRaghu Vatsavayi 	"rx_packets",
160d8ab848cSRaghu Vatsavayi 	"tx_packets",
161d8ab848cSRaghu Vatsavayi 	"rx_bytes",
162d8ab848cSRaghu Vatsavayi 	"tx_bytes",
163897ddc24SIntiyaz Basha 	"rx_errors",
164897ddc24SIntiyaz Basha 	"tx_errors",
165897ddc24SIntiyaz Basha 	"rx_dropped",
166d8ab848cSRaghu Vatsavayi 	"tx_dropped",
16780002347SPradeep Nalla 	"rx_mcast",
16880002347SPradeep Nalla 	"tx_mcast",
16980002347SPradeep Nalla 	"rx_bcast",
17080002347SPradeep Nalla 	"tx_bcast",
171d8ab848cSRaghu Vatsavayi 	"link_state_changes",
172d8ab848cSRaghu Vatsavayi };
173d8ab848cSRaghu Vatsavayi 
1741f164717SRaghu Vatsavayi /* statistics of host tx queue */
1751f164717SRaghu Vatsavayi static const char oct_iq_stats_strings[][ETH_GSTRING_LEN] = {
176897ddc24SIntiyaz Basha 	"packets",
177897ddc24SIntiyaz Basha 	"bytes",
1781f164717SRaghu Vatsavayi 	"dropped",
1791f164717SRaghu Vatsavayi 	"iq_busy",
1801f164717SRaghu Vatsavayi 	"sgentry_sent",
1811f164717SRaghu Vatsavayi 
1821f164717SRaghu Vatsavayi 	"fw_instr_posted",
1831f164717SRaghu Vatsavayi 	"fw_instr_processed",
1841f164717SRaghu Vatsavayi 	"fw_instr_dropped",
1851f164717SRaghu Vatsavayi 	"fw_bytes_sent",
1861f164717SRaghu Vatsavayi 
1871f164717SRaghu Vatsavayi 	"tso",
18801fb237aSRaghu Vatsavayi 	"vxlan",
1891f164717SRaghu Vatsavayi 	"txq_restart",
1901f164717SRaghu Vatsavayi };
1911f164717SRaghu Vatsavayi 
1921f164717SRaghu Vatsavayi /* statistics of host rx queue */
193f21fb3edSRaghu Vatsavayi static const char oct_droq_stats_strings[][ETH_GSTRING_LEN] = {
194897ddc24SIntiyaz Basha 	"packets",
195897ddc24SIntiyaz Basha 	"bytes",
196897ddc24SIntiyaz Basha 	"dropped",
1971f164717SRaghu Vatsavayi 	"dropped_nomem",
1981f164717SRaghu Vatsavayi 	"dropped_toomany",
1991f164717SRaghu Vatsavayi 	"fw_dropped",
2001f164717SRaghu Vatsavayi 	"fw_pkts_received",
2011f164717SRaghu Vatsavayi 	"fw_bytes_received",
2021f164717SRaghu Vatsavayi 	"fw_dropped_nodispatch",
2031f164717SRaghu Vatsavayi 
20401fb237aSRaghu Vatsavayi 	"vxlan",
2051f164717SRaghu Vatsavayi 	"buffer_alloc_failure",
206f21fb3edSRaghu Vatsavayi };
207f21fb3edSRaghu Vatsavayi 
20830136395SRaghu Vatsavayi /* LiquidIO driver private flags */
20930136395SRaghu Vatsavayi static const char oct_priv_flags_strings[][ETH_GSTRING_LEN] = {
21030136395SRaghu Vatsavayi };
21130136395SRaghu Vatsavayi 
212f21fb3edSRaghu Vatsavayi #define OCTNIC_NCMD_AUTONEG_ON  0x1
213f21fb3edSRaghu Vatsavayi #define OCTNIC_NCMD_PHY_ON      0x2
214f21fb3edSRaghu Vatsavayi 
lio_get_link_ksettings(struct net_device * netdev,struct ethtool_link_ksettings * ecmd)215d8ab848cSRaghu Vatsavayi static int lio_get_link_ksettings(struct net_device *netdev,
216d8ab848cSRaghu Vatsavayi 				  struct ethtool_link_ksettings *ecmd)
217f21fb3edSRaghu Vatsavayi {
218f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
219f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
220f21fb3edSRaghu Vatsavayi 	struct oct_link_info *linfo;
221f21fb3edSRaghu Vatsavayi 
222f21fb3edSRaghu Vatsavayi 	linfo = &lio->linfo;
223f21fb3edSRaghu Vatsavayi 
22418b338f5SWeilin Chang 	ethtool_link_ksettings_zero_link_mode(ecmd, supported);
22518b338f5SWeilin Chang 	ethtool_link_ksettings_zero_link_mode(ecmd, advertising);
22618b338f5SWeilin Chang 
2275677629aSVeerasenareddy Burru 	switch (linfo->link.s.phy_type) {
2285677629aSVeerasenareddy Burru 	case LIO_PHY_PORT_TP:
2295677629aSVeerasenareddy Burru 		ecmd->base.port = PORT_TP;
2305677629aSVeerasenareddy Burru 		ecmd->base.autoneg = AUTONEG_DISABLE;
23118b338f5SWeilin Chang 		ethtool_link_ksettings_add_link_mode(ecmd, supported, TP);
23218b338f5SWeilin Chang 		ethtool_link_ksettings_add_link_mode(ecmd, supported, Pause);
23318b338f5SWeilin Chang 		ethtool_link_ksettings_add_link_mode(ecmd, supported,
23418b338f5SWeilin Chang 						     10000baseT_Full);
23518b338f5SWeilin Chang 
23618b338f5SWeilin Chang 		ethtool_link_ksettings_add_link_mode(ecmd, advertising, Pause);
23718b338f5SWeilin Chang 		ethtool_link_ksettings_add_link_mode(ecmd, advertising,
23818b338f5SWeilin Chang 						     10000baseT_Full);
23918b338f5SWeilin Chang 
2405677629aSVeerasenareddy Burru 		break;
2415677629aSVeerasenareddy Burru 
2425677629aSVeerasenareddy Burru 	case LIO_PHY_PORT_FIBRE:
2435677629aSVeerasenareddy Burru 		if (linfo->link.s.if_mode == INTERFACE_MODE_XAUI ||
2445677629aSVeerasenareddy Burru 		    linfo->link.s.if_mode == INTERFACE_MODE_RXAUI ||
2455677629aSVeerasenareddy Burru 		    linfo->link.s.if_mode == INTERFACE_MODE_XLAUI ||
2465677629aSVeerasenareddy Burru 		    linfo->link.s.if_mode == INTERFACE_MODE_XFI) {
24718b338f5SWeilin Chang 			dev_dbg(&oct->pci_dev->dev, "ecmd->base.transceiver is XCVR_EXTERNAL\n");
24875b2c206SWeilin Chang 			ecmd->base.transceiver = XCVR_EXTERNAL;
249f21fb3edSRaghu Vatsavayi 		} else {
25018b338f5SWeilin Chang 			dev_err(&oct->pci_dev->dev, "Unknown link interface mode: %d\n",
2519eb60844SRaghu Vatsavayi 				linfo->link.s.if_mode);
252f21fb3edSRaghu Vatsavayi 		}
253f21fb3edSRaghu Vatsavayi 
25418b338f5SWeilin Chang 		ecmd->base.port = PORT_FIBRE;
25518b338f5SWeilin Chang 		ecmd->base.autoneg = AUTONEG_DISABLE;
25618b338f5SWeilin Chang 		ethtool_link_ksettings_add_link_mode(ecmd, supported, FIBRE);
25718b338f5SWeilin Chang 
25818b338f5SWeilin Chang 		ethtool_link_ksettings_add_link_mode(ecmd, supported, Pause);
25918b338f5SWeilin Chang 		ethtool_link_ksettings_add_link_mode(ecmd, advertising, Pause);
26018b338f5SWeilin Chang 		if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID ||
26118b338f5SWeilin Chang 		    oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) {
26218b338f5SWeilin Chang 			if (OCTEON_CN23XX_PF(oct)) {
26318b338f5SWeilin Chang 				ethtool_link_ksettings_add_link_mode
26418b338f5SWeilin Chang 					(ecmd, supported, 25000baseSR_Full);
26518b338f5SWeilin Chang 				ethtool_link_ksettings_add_link_mode
26618b338f5SWeilin Chang 					(ecmd, supported, 25000baseKR_Full);
26718b338f5SWeilin Chang 				ethtool_link_ksettings_add_link_mode
26818b338f5SWeilin Chang 					(ecmd, supported, 25000baseCR_Full);
26918b338f5SWeilin Chang 
27018b338f5SWeilin Chang 				if (oct->no_speed_setting == 0)  {
27118b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
27218b338f5SWeilin Chang 						(ecmd, supported,
27318b338f5SWeilin Chang 						 10000baseSR_Full);
27418b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
27518b338f5SWeilin Chang 						(ecmd, supported,
27618b338f5SWeilin Chang 						 10000baseKR_Full);
27718b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
27818b338f5SWeilin Chang 						(ecmd, supported,
27918b338f5SWeilin Chang 						 10000baseCR_Full);
28018b338f5SWeilin Chang 				}
28118b338f5SWeilin Chang 
28275b2c206SWeilin Chang 				if (oct->no_speed_setting == 0) {
28318b338f5SWeilin Chang 					liquidio_get_speed(lio);
28475b2c206SWeilin Chang 					liquidio_get_fec(lio);
28575b2c206SWeilin Chang 				} else {
28618b338f5SWeilin Chang 					oct->speed_setting = 25;
28775b2c206SWeilin Chang 				}
28818b338f5SWeilin Chang 
28918b338f5SWeilin Chang 				if (oct->speed_setting == 10) {
29018b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
29118b338f5SWeilin Chang 						(ecmd, advertising,
29218b338f5SWeilin Chang 						 10000baseSR_Full);
29318b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
29418b338f5SWeilin Chang 						(ecmd, advertising,
29518b338f5SWeilin Chang 						 10000baseKR_Full);
29618b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
29718b338f5SWeilin Chang 						(ecmd, advertising,
29818b338f5SWeilin Chang 						 10000baseCR_Full);
29918b338f5SWeilin Chang 				}
30018b338f5SWeilin Chang 				if (oct->speed_setting == 25) {
30118b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
30218b338f5SWeilin Chang 						(ecmd, advertising,
30318b338f5SWeilin Chang 						 25000baseSR_Full);
30418b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
30518b338f5SWeilin Chang 						(ecmd, advertising,
30618b338f5SWeilin Chang 						 25000baseKR_Full);
30718b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
30818b338f5SWeilin Chang 						(ecmd, advertising,
30918b338f5SWeilin Chang 						 25000baseCR_Full);
31018b338f5SWeilin Chang 				}
31175b2c206SWeilin Chang 
31275b2c206SWeilin Chang 				if (oct->no_speed_setting)
31375b2c206SWeilin Chang 					break;
31475b2c206SWeilin Chang 
31575b2c206SWeilin Chang 				ethtool_link_ksettings_add_link_mode
31675b2c206SWeilin Chang 					(ecmd, supported, FEC_RS);
31775b2c206SWeilin Chang 				ethtool_link_ksettings_add_link_mode
31875b2c206SWeilin Chang 					(ecmd, supported, FEC_NONE);
31975b2c206SWeilin Chang 					/*FEC_OFF*/
32075b2c206SWeilin Chang 				if (oct->props[lio->ifidx].fec == 1) {
32175b2c206SWeilin Chang 					/* ETHTOOL_FEC_RS */
32275b2c206SWeilin Chang 					ethtool_link_ksettings_add_link_mode
32375b2c206SWeilin Chang 						(ecmd, advertising, FEC_RS);
32475b2c206SWeilin Chang 				} else {
32575b2c206SWeilin Chang 					/* ETHTOOL_FEC_OFF */
32675b2c206SWeilin Chang 					ethtool_link_ksettings_add_link_mode
32775b2c206SWeilin Chang 						(ecmd, advertising, FEC_NONE);
32875b2c206SWeilin Chang 				}
32918b338f5SWeilin Chang 			} else { /* VF */
33018b338f5SWeilin Chang 				if (linfo->link.s.speed == 10000) {
33118b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
33218b338f5SWeilin Chang 						(ecmd, supported,
33318b338f5SWeilin Chang 						 10000baseSR_Full);
33418b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
33518b338f5SWeilin Chang 						(ecmd, supported,
33618b338f5SWeilin Chang 						 10000baseKR_Full);
33718b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
33818b338f5SWeilin Chang 						(ecmd, supported,
33918b338f5SWeilin Chang 						 10000baseCR_Full);
34018b338f5SWeilin Chang 
34118b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
34218b338f5SWeilin Chang 						(ecmd, advertising,
34318b338f5SWeilin Chang 						 10000baseSR_Full);
34418b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
34518b338f5SWeilin Chang 						(ecmd, advertising,
34618b338f5SWeilin Chang 						 10000baseKR_Full);
34718b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
34818b338f5SWeilin Chang 						(ecmd, advertising,
34918b338f5SWeilin Chang 						 10000baseCR_Full);
35018b338f5SWeilin Chang 				}
35118b338f5SWeilin Chang 
35218b338f5SWeilin Chang 				if (linfo->link.s.speed == 25000) {
35318b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
35418b338f5SWeilin Chang 						(ecmd, supported,
35518b338f5SWeilin Chang 						 25000baseSR_Full);
35618b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
35718b338f5SWeilin Chang 						(ecmd, supported,
35818b338f5SWeilin Chang 						 25000baseKR_Full);
35918b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
36018b338f5SWeilin Chang 						(ecmd, supported,
36118b338f5SWeilin Chang 						 25000baseCR_Full);
36218b338f5SWeilin Chang 
36318b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
36418b338f5SWeilin Chang 						(ecmd, advertising,
36518b338f5SWeilin Chang 						 25000baseSR_Full);
36618b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
36718b338f5SWeilin Chang 						(ecmd, advertising,
36818b338f5SWeilin Chang 						 25000baseKR_Full);
36918b338f5SWeilin Chang 					ethtool_link_ksettings_add_link_mode
37018b338f5SWeilin Chang 						(ecmd, advertising,
37118b338f5SWeilin Chang 						 25000baseCR_Full);
37218b338f5SWeilin Chang 				}
37318b338f5SWeilin Chang 			}
37418b338f5SWeilin Chang 		} else {
37518b338f5SWeilin Chang 			ethtool_link_ksettings_add_link_mode(ecmd, supported,
37618b338f5SWeilin Chang 							     10000baseT_Full);
37718b338f5SWeilin Chang 			ethtool_link_ksettings_add_link_mode(ecmd, advertising,
37818b338f5SWeilin Chang 							     10000baseT_Full);
37918b338f5SWeilin Chang 		}
38018b338f5SWeilin Chang 		break;
38118b338f5SWeilin Chang 	}
38218b338f5SWeilin Chang 
3830cece6c5SRaghu Vatsavayi 	if (linfo->link.s.link_up) {
384d8ab848cSRaghu Vatsavayi 		ecmd->base.speed = linfo->link.s.speed;
385d8ab848cSRaghu Vatsavayi 		ecmd->base.duplex = linfo->link.s.duplex;
386f21fb3edSRaghu Vatsavayi 	} else {
387d8ab848cSRaghu Vatsavayi 		ecmd->base.speed = SPEED_UNKNOWN;
388d8ab848cSRaghu Vatsavayi 		ecmd->base.duplex = DUPLEX_UNKNOWN;
389f21fb3edSRaghu Vatsavayi 	}
390f21fb3edSRaghu Vatsavayi 
391f21fb3edSRaghu Vatsavayi 	return 0;
392f21fb3edSRaghu Vatsavayi }
393f21fb3edSRaghu Vatsavayi 
lio_set_link_ksettings(struct net_device * netdev,const struct ethtool_link_ksettings * ecmd)39418b338f5SWeilin Chang static int lio_set_link_ksettings(struct net_device *netdev,
39518b338f5SWeilin Chang 				  const struct ethtool_link_ksettings *ecmd)
39618b338f5SWeilin Chang {
39718b338f5SWeilin Chang 	const int speed = ecmd->base.speed;
39818b338f5SWeilin Chang 	struct lio *lio = GET_LIO(netdev);
39918b338f5SWeilin Chang 	struct oct_link_info *linfo;
40018b338f5SWeilin Chang 	struct octeon_device *oct;
40118b338f5SWeilin Chang 
40218b338f5SWeilin Chang 	oct = lio->oct_dev;
40318b338f5SWeilin Chang 
40418b338f5SWeilin Chang 	linfo = &lio->linfo;
40518b338f5SWeilin Chang 
40645c91fb2SYueHaibing 	if (!(oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID ||
40745c91fb2SYueHaibing 	      oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID))
40818b338f5SWeilin Chang 		return -EOPNOTSUPP;
40918b338f5SWeilin Chang 
41018b338f5SWeilin Chang 	if (oct->no_speed_setting) {
41118b338f5SWeilin Chang 		dev_err(&oct->pci_dev->dev, "%s: Changing speed is not supported\n",
41218b338f5SWeilin Chang 			__func__);
41318b338f5SWeilin Chang 		return -EOPNOTSUPP;
41418b338f5SWeilin Chang 	}
41518b338f5SWeilin Chang 
41618b338f5SWeilin Chang 	if ((ecmd->base.duplex != DUPLEX_UNKNOWN &&
41718b338f5SWeilin Chang 	     ecmd->base.duplex != linfo->link.s.duplex) ||
41818b338f5SWeilin Chang 	     ecmd->base.autoneg != AUTONEG_DISABLE ||
41918b338f5SWeilin Chang 	    (ecmd->base.speed != 10000 && ecmd->base.speed != 25000 &&
42018b338f5SWeilin Chang 	     ecmd->base.speed != SPEED_UNKNOWN))
42118b338f5SWeilin Chang 		return -EOPNOTSUPP;
42218b338f5SWeilin Chang 
42318b338f5SWeilin Chang 	if ((oct->speed_boot == speed / 1000) &&
42418b338f5SWeilin Chang 	    oct->speed_boot == oct->speed_setting)
42518b338f5SWeilin Chang 		return 0;
42618b338f5SWeilin Chang 
42718b338f5SWeilin Chang 	liquidio_set_speed(lio, speed / 1000);
42818b338f5SWeilin Chang 
42918b338f5SWeilin Chang 	dev_dbg(&oct->pci_dev->dev, "Port speed is set to %dG\n",
43018b338f5SWeilin Chang 		oct->speed_setting);
43118b338f5SWeilin Chang 
43218b338f5SWeilin Chang 	return 0;
43318b338f5SWeilin Chang }
43418b338f5SWeilin Chang 
435f21fb3edSRaghu Vatsavayi static void
lio_get_drvinfo(struct net_device * netdev,struct ethtool_drvinfo * drvinfo)436f21fb3edSRaghu Vatsavayi lio_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
437f21fb3edSRaghu Vatsavayi {
438f21fb3edSRaghu Vatsavayi 	struct lio *lio;
439f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct;
440f21fb3edSRaghu Vatsavayi 
441f21fb3edSRaghu Vatsavayi 	lio = GET_LIO(netdev);
442f21fb3edSRaghu Vatsavayi 	oct = lio->oct_dev;
443f21fb3edSRaghu Vatsavayi 
444f21fb3edSRaghu Vatsavayi 	memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
445f21fb3edSRaghu Vatsavayi 	strcpy(drvinfo->driver, "liquidio");
446f21fb3edSRaghu Vatsavayi 	strncpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version,
447f21fb3edSRaghu Vatsavayi 		ETHTOOL_FWVERS_LEN);
448f21fb3edSRaghu Vatsavayi 	strncpy(drvinfo->bus_info, pci_name(oct->pci_dev), 32);
449f21fb3edSRaghu Vatsavayi }
450f21fb3edSRaghu Vatsavayi 
451f21fb3edSRaghu Vatsavayi static void
lio_get_vf_drvinfo(struct net_device * netdev,struct ethtool_drvinfo * drvinfo)452d8ab848cSRaghu Vatsavayi lio_get_vf_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
453d8ab848cSRaghu Vatsavayi {
454d8ab848cSRaghu Vatsavayi 	struct octeon_device *oct;
455d8ab848cSRaghu Vatsavayi 	struct lio *lio;
456d8ab848cSRaghu Vatsavayi 
457d8ab848cSRaghu Vatsavayi 	lio = GET_LIO(netdev);
458d8ab848cSRaghu Vatsavayi 	oct = lio->oct_dev;
459d8ab848cSRaghu Vatsavayi 
460d8ab848cSRaghu Vatsavayi 	memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
461d8ab848cSRaghu Vatsavayi 	strcpy(drvinfo->driver, "liquidio_vf");
462d8ab848cSRaghu Vatsavayi 	strncpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version,
463d8ab848cSRaghu Vatsavayi 		ETHTOOL_FWVERS_LEN);
464d8ab848cSRaghu Vatsavayi 	strncpy(drvinfo->bus_info, pci_name(oct->pci_dev), 32);
465d8ab848cSRaghu Vatsavayi }
466d8ab848cSRaghu Vatsavayi 
467a82457f1SIntiyaz Basha static int
lio_send_queue_count_update(struct net_device * netdev,uint32_t num_queues)468a82457f1SIntiyaz Basha lio_send_queue_count_update(struct net_device *netdev, uint32_t num_queues)
469a82457f1SIntiyaz Basha {
470a82457f1SIntiyaz Basha 	struct lio *lio = GET_LIO(netdev);
471a82457f1SIntiyaz Basha 	struct octeon_device *oct = lio->oct_dev;
472a82457f1SIntiyaz Basha 	struct octnic_ctrl_pkt nctrl;
473a82457f1SIntiyaz Basha 	int ret = 0;
474a82457f1SIntiyaz Basha 
475a82457f1SIntiyaz Basha 	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
476a82457f1SIntiyaz Basha 
477a82457f1SIntiyaz Basha 	nctrl.ncmd.u64 = 0;
478a82457f1SIntiyaz Basha 	nctrl.ncmd.s.cmd = OCTNET_CMD_QUEUE_COUNT_CTL;
479a82457f1SIntiyaz Basha 	nctrl.ncmd.s.param1 = num_queues;
480a82457f1SIntiyaz Basha 	nctrl.ncmd.s.param2 = num_queues;
481a82457f1SIntiyaz Basha 	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
482a82457f1SIntiyaz Basha 	nctrl.netpndev = (u64)netdev;
483a82457f1SIntiyaz Basha 	nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
484a82457f1SIntiyaz Basha 
485a82457f1SIntiyaz Basha 	ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
486edd572d7SFelix Manlunas 	if (ret) {
487a82457f1SIntiyaz Basha 		dev_err(&oct->pci_dev->dev, "Failed to send Queue reset command (ret: 0x%x)\n",
488a82457f1SIntiyaz Basha 			ret);
489a82457f1SIntiyaz Basha 		return -1;
490a82457f1SIntiyaz Basha 	}
491a82457f1SIntiyaz Basha 
492a82457f1SIntiyaz Basha 	return 0;
493a82457f1SIntiyaz Basha }
494a82457f1SIntiyaz Basha 
495d8ab848cSRaghu Vatsavayi static void
lio_ethtool_get_channels(struct net_device * dev,struct ethtool_channels * channel)496f21fb3edSRaghu Vatsavayi lio_ethtool_get_channels(struct net_device *dev,
497f21fb3edSRaghu Vatsavayi 			 struct ethtool_channels *channel)
498f21fb3edSRaghu Vatsavayi {
499f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(dev);
500f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
501f21fb3edSRaghu Vatsavayi 	u32 max_rx = 0, max_tx = 0, tx_count = 0, rx_count = 0;
502a82457f1SIntiyaz Basha 	u32 combined_count = 0, max_combined = 0;
503f21fb3edSRaghu Vatsavayi 
504f21fb3edSRaghu Vatsavayi 	if (OCTEON_CN6XXX(oct)) {
50597a25326SRaghu Vatsavayi 		struct octeon_config *conf6x = CHIP_CONF(oct, cn6xxx);
506f21fb3edSRaghu Vatsavayi 
507f21fb3edSRaghu Vatsavayi 		max_rx = CFG_GET_OQ_MAX_Q(conf6x);
508f21fb3edSRaghu Vatsavayi 		max_tx = CFG_GET_IQ_MAX_Q(conf6x);
509f21fb3edSRaghu Vatsavayi 		rx_count = CFG_GET_NUM_RXQS_NIC_IF(conf6x, lio->ifidx);
510f21fb3edSRaghu Vatsavayi 		tx_count = CFG_GET_NUM_TXQS_NIC_IF(conf6x, lio->ifidx);
511dc3abcbeSRaghu Vatsavayi 	} else if (OCTEON_CN23XX_PF(oct)) {
512c33c9973SIntiyaz Basha 		if (oct->sriov_info.sriov_enabled) {
513a82457f1SIntiyaz Basha 			max_combined = lio->linfo.num_txpciq;
514c33c9973SIntiyaz Basha 		} else {
515c33c9973SIntiyaz Basha 			struct octeon_config *conf23_pf =
516c33c9973SIntiyaz Basha 				CHIP_CONF(oct, cn23xx_pf);
517c33c9973SIntiyaz Basha 
518c33c9973SIntiyaz Basha 			max_combined = CFG_GET_IQ_MAX_Q(conf23_pf);
519c33c9973SIntiyaz Basha 		}
520a82457f1SIntiyaz Basha 		combined_count = oct->num_iqs;
521026b471bSWeilin Chang 	} else if (OCTEON_CN23XX_VF(oct)) {
522a82457f1SIntiyaz Basha 		u64 reg_val = 0ULL;
523a82457f1SIntiyaz Basha 		u64 ctrl = CN23XX_VF_SLI_IQ_PKT_CONTROL64(0);
524a82457f1SIntiyaz Basha 
525a82457f1SIntiyaz Basha 		reg_val = octeon_read_csr64(oct, ctrl);
526a82457f1SIntiyaz Basha 		reg_val = reg_val >> CN23XX_PKT_INPUT_CTL_RPVF_POS;
527a82457f1SIntiyaz Basha 		max_combined = reg_val & CN23XX_PKT_INPUT_CTL_RPVF_MASK;
528a82457f1SIntiyaz Basha 		combined_count = oct->num_iqs;
529f21fb3edSRaghu Vatsavayi 	}
530f21fb3edSRaghu Vatsavayi 
531f21fb3edSRaghu Vatsavayi 	channel->max_rx = max_rx;
532f21fb3edSRaghu Vatsavayi 	channel->max_tx = max_tx;
533a82457f1SIntiyaz Basha 	channel->max_combined = max_combined;
534f21fb3edSRaghu Vatsavayi 	channel->rx_count = rx_count;
535f21fb3edSRaghu Vatsavayi 	channel->tx_count = tx_count;
536a82457f1SIntiyaz Basha 	channel->combined_count = combined_count;
537a82457f1SIntiyaz Basha }
538a82457f1SIntiyaz Basha 
539a82457f1SIntiyaz Basha static int
lio_irq_reallocate_irqs(struct octeon_device * oct,uint32_t num_ioqs)540a82457f1SIntiyaz Basha lio_irq_reallocate_irqs(struct octeon_device *oct, uint32_t num_ioqs)
541a82457f1SIntiyaz Basha {
542a82457f1SIntiyaz Basha 	struct msix_entry *msix_entries;
543a82457f1SIntiyaz Basha 	int num_msix_irqs = 0;
544a82457f1SIntiyaz Basha 	int i;
545a82457f1SIntiyaz Basha 
546a82457f1SIntiyaz Basha 	if (!oct->msix_on)
547a82457f1SIntiyaz Basha 		return 0;
548a82457f1SIntiyaz Basha 
549a82457f1SIntiyaz Basha 	/* Disable the input and output queues now. No more packets will
550a82457f1SIntiyaz Basha 	 * arrive from Octeon.
551a82457f1SIntiyaz Basha 	 */
552a82457f1SIntiyaz Basha 	oct->fn_list.disable_interrupt(oct, OCTEON_ALL_INTR);
553a82457f1SIntiyaz Basha 
554a82457f1SIntiyaz Basha 	if (oct->msix_on) {
555a82457f1SIntiyaz Basha 		if (OCTEON_CN23XX_PF(oct))
556a82457f1SIntiyaz Basha 			num_msix_irqs = oct->num_msix_irqs - 1;
557a82457f1SIntiyaz Basha 		else if (OCTEON_CN23XX_VF(oct))
558a82457f1SIntiyaz Basha 			num_msix_irqs = oct->num_msix_irqs;
559a82457f1SIntiyaz Basha 
560a82457f1SIntiyaz Basha 		msix_entries = (struct msix_entry *)oct->msix_entries;
561a82457f1SIntiyaz Basha 		for (i = 0; i < num_msix_irqs; i++) {
562a82457f1SIntiyaz Basha 			if (oct->ioq_vector[i].vector) {
563a82457f1SIntiyaz Basha 				/* clear the affinity_cpumask */
564a82457f1SIntiyaz Basha 				irq_set_affinity_hint(msix_entries[i].vector,
565a82457f1SIntiyaz Basha 						      NULL);
566a82457f1SIntiyaz Basha 				free_irq(msix_entries[i].vector,
567a82457f1SIntiyaz Basha 					 &oct->ioq_vector[i]);
568a82457f1SIntiyaz Basha 				oct->ioq_vector[i].vector = 0;
569a82457f1SIntiyaz Basha 			}
570a82457f1SIntiyaz Basha 		}
571a82457f1SIntiyaz Basha 
572a82457f1SIntiyaz Basha 		/* non-iov vector's argument is oct struct */
573a82457f1SIntiyaz Basha 		if (OCTEON_CN23XX_PF(oct))
574a82457f1SIntiyaz Basha 			free_irq(msix_entries[i].vector, oct);
575a82457f1SIntiyaz Basha 
576a82457f1SIntiyaz Basha 		pci_disable_msix(oct->pci_dev);
577a82457f1SIntiyaz Basha 		kfree(oct->msix_entries);
578a82457f1SIntiyaz Basha 		oct->msix_entries = NULL;
579a82457f1SIntiyaz Basha 	}
580a82457f1SIntiyaz Basha 
581a82457f1SIntiyaz Basha 	kfree(oct->irq_name_storage);
582a82457f1SIntiyaz Basha 	oct->irq_name_storage = NULL;
583c33c9973SIntiyaz Basha 
584c33c9973SIntiyaz Basha 	if (octeon_allocate_ioq_vector(oct, num_ioqs)) {
585c33c9973SIntiyaz Basha 		dev_err(&oct->pci_dev->dev, "OCTEON: ioq vector allocation failed\n");
586c33c9973SIntiyaz Basha 		return -1;
587c33c9973SIntiyaz Basha 	}
588c33c9973SIntiyaz Basha 
589a82457f1SIntiyaz Basha 	if (octeon_setup_interrupt(oct, num_ioqs)) {
59093345c06SColin Ian King 		dev_info(&oct->pci_dev->dev, "Setup interrupt failed\n");
591c33c9973SIntiyaz Basha 		return -1;
592a82457f1SIntiyaz Basha 	}
593a82457f1SIntiyaz Basha 
594a82457f1SIntiyaz Basha 	/* Enable Octeon device interrupts */
595a82457f1SIntiyaz Basha 	oct->fn_list.enable_interrupt(oct, OCTEON_ALL_INTR);
596a82457f1SIntiyaz Basha 
597a82457f1SIntiyaz Basha 	return 0;
598a82457f1SIntiyaz Basha }
599a82457f1SIntiyaz Basha 
600a82457f1SIntiyaz Basha static int
lio_ethtool_set_channels(struct net_device * dev,struct ethtool_channels * channel)601a82457f1SIntiyaz Basha lio_ethtool_set_channels(struct net_device *dev,
602a82457f1SIntiyaz Basha 			 struct ethtool_channels *channel)
603a82457f1SIntiyaz Basha {
604a82457f1SIntiyaz Basha 	u32 combined_count, max_combined;
605a82457f1SIntiyaz Basha 	struct lio *lio = GET_LIO(dev);
606a82457f1SIntiyaz Basha 	struct octeon_device *oct = lio->oct_dev;
607a82457f1SIntiyaz Basha 	int stopped = 0;
608a82457f1SIntiyaz Basha 
609a82457f1SIntiyaz Basha 	if (strcmp(oct->fw_info.liquidio_firmware_version, "1.6.1") < 0) {
610a82457f1SIntiyaz Basha 		dev_err(&oct->pci_dev->dev, "Minimum firmware version required is 1.6.1\n");
611a82457f1SIntiyaz Basha 		return -EINVAL;
612a82457f1SIntiyaz Basha 	}
613a82457f1SIntiyaz Basha 
614a82457f1SIntiyaz Basha 	if (!channel->combined_count || channel->other_count ||
615a82457f1SIntiyaz Basha 	    channel->rx_count || channel->tx_count)
616a82457f1SIntiyaz Basha 		return -EINVAL;
617a82457f1SIntiyaz Basha 
618a82457f1SIntiyaz Basha 	combined_count = channel->combined_count;
619a82457f1SIntiyaz Basha 
620a82457f1SIntiyaz Basha 	if (OCTEON_CN23XX_PF(oct)) {
621c33c9973SIntiyaz Basha 		if (oct->sriov_info.sriov_enabled) {
622c33c9973SIntiyaz Basha 			max_combined = lio->linfo.num_txpciq;
623c33c9973SIntiyaz Basha 		} else {
624c33c9973SIntiyaz Basha 			struct octeon_config *conf23_pf =
625c33c9973SIntiyaz Basha 				CHIP_CONF(oct,
626c33c9973SIntiyaz Basha 					  cn23xx_pf);
627c33c9973SIntiyaz Basha 
628c33c9973SIntiyaz Basha 			max_combined =
629c33c9973SIntiyaz Basha 				CFG_GET_IQ_MAX_Q(conf23_pf);
630c33c9973SIntiyaz Basha 		}
631a82457f1SIntiyaz Basha 	} else if (OCTEON_CN23XX_VF(oct)) {
632a82457f1SIntiyaz Basha 		u64 reg_val = 0ULL;
633a82457f1SIntiyaz Basha 		u64 ctrl = CN23XX_VF_SLI_IQ_PKT_CONTROL64(0);
634a82457f1SIntiyaz Basha 
635a82457f1SIntiyaz Basha 		reg_val = octeon_read_csr64(oct, ctrl);
636a82457f1SIntiyaz Basha 		reg_val = reg_val >> CN23XX_PKT_INPUT_CTL_RPVF_POS;
637a82457f1SIntiyaz Basha 		max_combined = reg_val & CN23XX_PKT_INPUT_CTL_RPVF_MASK;
638a82457f1SIntiyaz Basha 	} else {
639a82457f1SIntiyaz Basha 		return -EINVAL;
640a82457f1SIntiyaz Basha 	}
641a82457f1SIntiyaz Basha 
642a82457f1SIntiyaz Basha 	if (combined_count > max_combined || combined_count < 1)
643a82457f1SIntiyaz Basha 		return -EINVAL;
644a82457f1SIntiyaz Basha 
645a82457f1SIntiyaz Basha 	if (combined_count == oct->num_iqs)
646a82457f1SIntiyaz Basha 		return 0;
647a82457f1SIntiyaz Basha 
648a82457f1SIntiyaz Basha 	ifstate_set(lio, LIO_IFSTATE_RESETTING);
649a82457f1SIntiyaz Basha 
650a82457f1SIntiyaz Basha 	if (netif_running(dev)) {
651a82457f1SIntiyaz Basha 		dev->netdev_ops->ndo_stop(dev);
652a82457f1SIntiyaz Basha 		stopped = 1;
653a82457f1SIntiyaz Basha 	}
654a82457f1SIntiyaz Basha 
655a82457f1SIntiyaz Basha 	if (lio_reset_queues(dev, combined_count))
656a82457f1SIntiyaz Basha 		return -EINVAL;
657a82457f1SIntiyaz Basha 
658a82457f1SIntiyaz Basha 	if (stopped)
659a82457f1SIntiyaz Basha 		dev->netdev_ops->ndo_open(dev);
660a82457f1SIntiyaz Basha 
661a82457f1SIntiyaz Basha 	ifstate_reset(lio, LIO_IFSTATE_RESETTING);
662a82457f1SIntiyaz Basha 
663a82457f1SIntiyaz Basha 	return 0;
664f21fb3edSRaghu Vatsavayi }
665f21fb3edSRaghu Vatsavayi 
lio_get_eeprom_len(struct net_device * netdev)666f21fb3edSRaghu Vatsavayi static int lio_get_eeprom_len(struct net_device *netdev)
667f21fb3edSRaghu Vatsavayi {
66856c0da49SArnd Bergmann 	u8 buf[192];
669f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
670f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
671f21fb3edSRaghu Vatsavayi 	struct octeon_board_info *board_info;
672f21fb3edSRaghu Vatsavayi 	int len;
673f21fb3edSRaghu Vatsavayi 
674f21fb3edSRaghu Vatsavayi 	board_info = (struct octeon_board_info *)(&oct_dev->boardinfo);
675f21fb3edSRaghu Vatsavayi 	len = sprintf(buf, "boardname:%s serialnum:%s maj:%lld min:%lld\n",
676f21fb3edSRaghu Vatsavayi 		      board_info->name, board_info->serial_number,
677f21fb3edSRaghu Vatsavayi 		      board_info->major, board_info->minor);
678f21fb3edSRaghu Vatsavayi 
679f21fb3edSRaghu Vatsavayi 	return len;
680f21fb3edSRaghu Vatsavayi }
681f21fb3edSRaghu Vatsavayi 
682f21fb3edSRaghu Vatsavayi static int
lio_get_eeprom(struct net_device * netdev,struct ethtool_eeprom * eeprom,u8 * bytes)683f21fb3edSRaghu Vatsavayi lio_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
684f21fb3edSRaghu Vatsavayi 	       u8 *bytes)
685f21fb3edSRaghu Vatsavayi {
686f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
687f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
688f21fb3edSRaghu Vatsavayi 	struct octeon_board_info *board_info;
689f21fb3edSRaghu Vatsavayi 
69032581245SRaghu Vatsavayi 	if (eeprom->offset)
691f21fb3edSRaghu Vatsavayi 		return -EINVAL;
692f21fb3edSRaghu Vatsavayi 
693f21fb3edSRaghu Vatsavayi 	eeprom->magic = oct_dev->pci_dev->vendor;
694f21fb3edSRaghu Vatsavayi 	board_info = (struct octeon_board_info *)(&oct_dev->boardinfo);
695f21fb3edSRaghu Vatsavayi 	sprintf((char *)bytes,
696f21fb3edSRaghu Vatsavayi 		"boardname:%s serialnum:%s maj:%lld min:%lld\n",
697f21fb3edSRaghu Vatsavayi 		board_info->name, board_info->serial_number,
698f21fb3edSRaghu Vatsavayi 		board_info->major, board_info->minor);
699f21fb3edSRaghu Vatsavayi 
700f21fb3edSRaghu Vatsavayi 	return 0;
701f21fb3edSRaghu Vatsavayi }
702f21fb3edSRaghu Vatsavayi 
octnet_gpio_access(struct net_device * netdev,int addr,int val)703f21fb3edSRaghu Vatsavayi static int octnet_gpio_access(struct net_device *netdev, int addr, int val)
704f21fb3edSRaghu Vatsavayi {
705f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
706f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
707f21fb3edSRaghu Vatsavayi 	struct octnic_ctrl_pkt nctrl;
708f21fb3edSRaghu Vatsavayi 	int ret = 0;
709f21fb3edSRaghu Vatsavayi 
710f21fb3edSRaghu Vatsavayi 	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
711f21fb3edSRaghu Vatsavayi 
712f21fb3edSRaghu Vatsavayi 	nctrl.ncmd.u64 = 0;
713f21fb3edSRaghu Vatsavayi 	nctrl.ncmd.s.cmd = OCTNET_CMD_GPIO_ACCESS;
7140cece6c5SRaghu Vatsavayi 	nctrl.ncmd.s.param1 = addr;
7150cece6c5SRaghu Vatsavayi 	nctrl.ncmd.s.param2 = val;
7160cece6c5SRaghu Vatsavayi 	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
717f21fb3edSRaghu Vatsavayi 	nctrl.netpndev = (u64)netdev;
718f21fb3edSRaghu Vatsavayi 	nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
719f21fb3edSRaghu Vatsavayi 
7200cece6c5SRaghu Vatsavayi 	ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
721edd572d7SFelix Manlunas 	if (ret) {
722edd572d7SFelix Manlunas 		dev_err(&oct->pci_dev->dev,
723edd572d7SFelix Manlunas 			"Failed to configure gpio value, ret=%d\n", ret);
724f21fb3edSRaghu Vatsavayi 		return -EINVAL;
725f21fb3edSRaghu Vatsavayi 	}
726f21fb3edSRaghu Vatsavayi 
727f21fb3edSRaghu Vatsavayi 	return 0;
728f21fb3edSRaghu Vatsavayi }
729f21fb3edSRaghu Vatsavayi 
octnet_id_active(struct net_device * netdev,int val)730dc3abcbeSRaghu Vatsavayi static int octnet_id_active(struct net_device *netdev, int val)
731dc3abcbeSRaghu Vatsavayi {
732dc3abcbeSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
733dc3abcbeSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
734dc3abcbeSRaghu Vatsavayi 	struct octnic_ctrl_pkt nctrl;
735dc3abcbeSRaghu Vatsavayi 	int ret = 0;
736dc3abcbeSRaghu Vatsavayi 
737dc3abcbeSRaghu Vatsavayi 	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
738dc3abcbeSRaghu Vatsavayi 
739dc3abcbeSRaghu Vatsavayi 	nctrl.ncmd.u64 = 0;
740dc3abcbeSRaghu Vatsavayi 	nctrl.ncmd.s.cmd = OCTNET_CMD_ID_ACTIVE;
741dc3abcbeSRaghu Vatsavayi 	nctrl.ncmd.s.param1 = val;
742dc3abcbeSRaghu Vatsavayi 	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
743dc3abcbeSRaghu Vatsavayi 	nctrl.netpndev = (u64)netdev;
744dc3abcbeSRaghu Vatsavayi 	nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
745dc3abcbeSRaghu Vatsavayi 
746dc3abcbeSRaghu Vatsavayi 	ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
747edd572d7SFelix Manlunas 	if (ret) {
748edd572d7SFelix Manlunas 		dev_err(&oct->pci_dev->dev,
749edd572d7SFelix Manlunas 			"Failed to configure gpio value, ret=%d\n", ret);
750dc3abcbeSRaghu Vatsavayi 		return -EINVAL;
751dc3abcbeSRaghu Vatsavayi 	}
752dc3abcbeSRaghu Vatsavayi 
753dc3abcbeSRaghu Vatsavayi 	return 0;
754dc3abcbeSRaghu Vatsavayi }
755dc3abcbeSRaghu Vatsavayi 
756f21fb3edSRaghu Vatsavayi /* This routine provides PHY access routines for
757f21fb3edSRaghu Vatsavayi  * mdio  clause45 .
758f21fb3edSRaghu Vatsavayi  */
759f21fb3edSRaghu Vatsavayi static int
octnet_mdio45_access(struct lio * lio,int op,int loc,int * value)760f21fb3edSRaghu Vatsavayi octnet_mdio45_access(struct lio *lio, int op, int loc, int *value)
761f21fb3edSRaghu Vatsavayi {
762f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
763f21fb3edSRaghu Vatsavayi 	struct octeon_soft_command *sc;
764f21fb3edSRaghu Vatsavayi 	struct oct_mdio_cmd_resp *mdio_cmd_rsp;
765f21fb3edSRaghu Vatsavayi 	struct oct_mdio_cmd *mdio_cmd;
766f21fb3edSRaghu Vatsavayi 	int retval = 0;
767f21fb3edSRaghu Vatsavayi 
768f21fb3edSRaghu Vatsavayi 	sc = (struct octeon_soft_command *)
769f21fb3edSRaghu Vatsavayi 		octeon_alloc_soft_command(oct_dev,
770f21fb3edSRaghu Vatsavayi 					  sizeof(struct oct_mdio_cmd),
77164fecd3eSFelix Manlunas 					  sizeof(struct oct_mdio_cmd_resp), 0);
772f21fb3edSRaghu Vatsavayi 
773f21fb3edSRaghu Vatsavayi 	if (!sc)
774f21fb3edSRaghu Vatsavayi 		return -ENOMEM;
775f21fb3edSRaghu Vatsavayi 
776f21fb3edSRaghu Vatsavayi 	mdio_cmd_rsp = (struct oct_mdio_cmd_resp *)sc->virtrptr;
777f21fb3edSRaghu Vatsavayi 	mdio_cmd = (struct oct_mdio_cmd *)sc->virtdptr;
778f21fb3edSRaghu Vatsavayi 
779f21fb3edSRaghu Vatsavayi 	mdio_cmd->op = op;
780f21fb3edSRaghu Vatsavayi 	mdio_cmd->mdio_addr = loc;
781f21fb3edSRaghu Vatsavayi 	if (op)
782f21fb3edSRaghu Vatsavayi 		mdio_cmd->value1 = *value;
783f21fb3edSRaghu Vatsavayi 	octeon_swap_8B_data((u64 *)mdio_cmd, sizeof(struct oct_mdio_cmd) / 8);
784f21fb3edSRaghu Vatsavayi 
7850cece6c5SRaghu Vatsavayi 	sc->iq_no = lio->linfo.txpciq[0].s.q_no;
7860cece6c5SRaghu Vatsavayi 
787f21fb3edSRaghu Vatsavayi 	octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, OPCODE_NIC_MDIO45,
788f21fb3edSRaghu Vatsavayi 				    0, 0, 0);
789f21fb3edSRaghu Vatsavayi 
79064fecd3eSFelix Manlunas 	init_completion(&sc->complete);
79164fecd3eSFelix Manlunas 	sc->sc_status = OCTEON_REQUEST_PENDING;
792f21fb3edSRaghu Vatsavayi 
793f21fb3edSRaghu Vatsavayi 	retval = octeon_send_soft_command(oct_dev, sc);
794ddc173a6SRaghu Vatsavayi 	if (retval == IQ_SEND_FAILED) {
795f21fb3edSRaghu Vatsavayi 		dev_err(&oct_dev->pci_dev->dev,
796f21fb3edSRaghu Vatsavayi 			"octnet_mdio45_access instruction failed status: %x\n",
797f21fb3edSRaghu Vatsavayi 			retval);
79864fecd3eSFelix Manlunas 		octeon_free_soft_command(oct_dev, sc);
79964fecd3eSFelix Manlunas 		return -EBUSY;
800f21fb3edSRaghu Vatsavayi 	} else {
801f21fb3edSRaghu Vatsavayi 		/* Sleep on a wait queue till the cond flag indicates that the
802f21fb3edSRaghu Vatsavayi 		 * response arrived
803f21fb3edSRaghu Vatsavayi 		 */
80464fecd3eSFelix Manlunas 		retval = wait_for_sc_completion_timeout(oct_dev, sc, 0);
80564fecd3eSFelix Manlunas 		if (retval)
80664fecd3eSFelix Manlunas 			return retval;
80764fecd3eSFelix Manlunas 
808f21fb3edSRaghu Vatsavayi 		retval = mdio_cmd_rsp->status;
809f21fb3edSRaghu Vatsavayi 		if (retval) {
81064fecd3eSFelix Manlunas 			dev_err(&oct_dev->pci_dev->dev,
81164fecd3eSFelix Manlunas 				"octnet mdio45 access failed: %x\n", retval);
81264fecd3eSFelix Manlunas 			WRITE_ONCE(sc->caller_is_done, true);
81364fecd3eSFelix Manlunas 			return -EBUSY;
81464fecd3eSFelix Manlunas 		}
81564fecd3eSFelix Manlunas 
816f21fb3edSRaghu Vatsavayi 		octeon_swap_8B_data((u64 *)(&mdio_cmd_rsp->resp),
817f21fb3edSRaghu Vatsavayi 				    sizeof(struct oct_mdio_cmd) / 8);
818f21fb3edSRaghu Vatsavayi 
819f21fb3edSRaghu Vatsavayi 		if (!op)
820f21fb3edSRaghu Vatsavayi 			*value = mdio_cmd_rsp->resp.value1;
821f21fb3edSRaghu Vatsavayi 
82264fecd3eSFelix Manlunas 		WRITE_ONCE(sc->caller_is_done, true);
82364fecd3eSFelix Manlunas 	}
824f21fb3edSRaghu Vatsavayi 
825f21fb3edSRaghu Vatsavayi 	return retval;
826f21fb3edSRaghu Vatsavayi }
827f21fb3edSRaghu Vatsavayi 
lio_set_phys_id(struct net_device * netdev,enum ethtool_phys_id_state state)828f21fb3edSRaghu Vatsavayi static int lio_set_phys_id(struct net_device *netdev,
829f21fb3edSRaghu Vatsavayi 			   enum ethtool_phys_id_state state)
830f21fb3edSRaghu Vatsavayi {
831f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
832f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
8330520344cSRaghu Vatsavayi 	struct oct_link_info *linfo;
834f21fb3edSRaghu Vatsavayi 	int value, ret;
8350520344cSRaghu Vatsavayi 	u32 cur_ver;
8360520344cSRaghu Vatsavayi 
8370520344cSRaghu Vatsavayi 	linfo = &lio->linfo;
8380520344cSRaghu Vatsavayi 	cur_ver = OCT_FW_VER(oct->fw_info.ver.maj,
8390520344cSRaghu Vatsavayi 			     oct->fw_info.ver.min,
8400520344cSRaghu Vatsavayi 			     oct->fw_info.ver.rev);
841f21fb3edSRaghu Vatsavayi 
842f21fb3edSRaghu Vatsavayi 	switch (state) {
843f21fb3edSRaghu Vatsavayi 	case ETHTOOL_ID_ACTIVE:
844f21fb3edSRaghu Vatsavayi 		if (oct->chip_id == OCTEON_CN66XX) {
845f21fb3edSRaghu Vatsavayi 			octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
846f21fb3edSRaghu Vatsavayi 					   VITESSE_PHY_GPIO_DRIVEON);
847f21fb3edSRaghu Vatsavayi 			return 2;
848f21fb3edSRaghu Vatsavayi 
849f21fb3edSRaghu Vatsavayi 		} else if (oct->chip_id == OCTEON_CN68XX) {
850f21fb3edSRaghu Vatsavayi 			/* Save the current LED settings */
851f21fb3edSRaghu Vatsavayi 			ret = octnet_mdio45_access(lio, 0,
852f21fb3edSRaghu Vatsavayi 						   LIO68XX_LED_BEACON_ADDR,
853f21fb3edSRaghu Vatsavayi 						   &lio->phy_beacon_val);
854f21fb3edSRaghu Vatsavayi 			if (ret)
855f21fb3edSRaghu Vatsavayi 				return ret;
856f21fb3edSRaghu Vatsavayi 
857f21fb3edSRaghu Vatsavayi 			ret = octnet_mdio45_access(lio, 0,
858f21fb3edSRaghu Vatsavayi 						   LIO68XX_LED_CTRL_ADDR,
859f21fb3edSRaghu Vatsavayi 						   &lio->led_ctrl_val);
860f21fb3edSRaghu Vatsavayi 			if (ret)
861f21fb3edSRaghu Vatsavayi 				return ret;
862f21fb3edSRaghu Vatsavayi 
863f21fb3edSRaghu Vatsavayi 			/* Configure Beacon values */
864f21fb3edSRaghu Vatsavayi 			value = LIO68XX_LED_BEACON_CFGON;
865a2c64b67SRaghu Vatsavayi 			ret = octnet_mdio45_access(lio, 1,
866f21fb3edSRaghu Vatsavayi 						   LIO68XX_LED_BEACON_ADDR,
867f21fb3edSRaghu Vatsavayi 						   &value);
868f21fb3edSRaghu Vatsavayi 			if (ret)
869f21fb3edSRaghu Vatsavayi 				return ret;
870f21fb3edSRaghu Vatsavayi 
871f21fb3edSRaghu Vatsavayi 			value = LIO68XX_LED_CTRL_CFGON;
872a2c64b67SRaghu Vatsavayi 			ret = octnet_mdio45_access(lio, 1,
873f21fb3edSRaghu Vatsavayi 						   LIO68XX_LED_CTRL_ADDR,
874f21fb3edSRaghu Vatsavayi 						   &value);
875f21fb3edSRaghu Vatsavayi 			if (ret)
876f21fb3edSRaghu Vatsavayi 				return ret;
877dc3abcbeSRaghu Vatsavayi 		} else if (oct->chip_id == OCTEON_CN23XX_PF_VID) {
878dc3abcbeSRaghu Vatsavayi 			octnet_id_active(netdev, LED_IDENTIFICATION_ON);
8790520344cSRaghu Vatsavayi 			if (linfo->link.s.phy_type == LIO_PHY_PORT_TP &&
8800520344cSRaghu Vatsavayi 			    cur_ver > OCT_FW_VER(1, 7, 2))
8810520344cSRaghu Vatsavayi 				return 2;
8820520344cSRaghu Vatsavayi 			else
883dc3abcbeSRaghu Vatsavayi 				return 0;
884f21fb3edSRaghu Vatsavayi 		} else {
885f21fb3edSRaghu Vatsavayi 			return -EINVAL;
886f21fb3edSRaghu Vatsavayi 		}
887f21fb3edSRaghu Vatsavayi 		break;
888f21fb3edSRaghu Vatsavayi 
889f21fb3edSRaghu Vatsavayi 	case ETHTOOL_ID_ON:
8900520344cSRaghu Vatsavayi 		if (oct->chip_id == OCTEON_CN23XX_PF_VID &&
8910520344cSRaghu Vatsavayi 		    linfo->link.s.phy_type == LIO_PHY_PORT_TP &&
8920520344cSRaghu Vatsavayi 		    cur_ver > OCT_FW_VER(1, 7, 2))
8930520344cSRaghu Vatsavayi 			octnet_id_active(netdev, LED_IDENTIFICATION_ON);
8940520344cSRaghu Vatsavayi 		else if (oct->chip_id == OCTEON_CN66XX)
895f21fb3edSRaghu Vatsavayi 			octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
896f21fb3edSRaghu Vatsavayi 					   VITESSE_PHY_GPIO_HIGH);
897b5e7dc47SGustavo A. R. Silva 		else
898b5e7dc47SGustavo A. R. Silva 			return -EINVAL;
899f21fb3edSRaghu Vatsavayi 
900f21fb3edSRaghu Vatsavayi 		break;
901f21fb3edSRaghu Vatsavayi 
902f21fb3edSRaghu Vatsavayi 	case ETHTOOL_ID_OFF:
9030520344cSRaghu Vatsavayi 		if (oct->chip_id == OCTEON_CN23XX_PF_VID &&
9040520344cSRaghu Vatsavayi 		    linfo->link.s.phy_type == LIO_PHY_PORT_TP &&
9050520344cSRaghu Vatsavayi 		    cur_ver > OCT_FW_VER(1, 7, 2))
9060520344cSRaghu Vatsavayi 			octnet_id_active(netdev, LED_IDENTIFICATION_OFF);
9070520344cSRaghu Vatsavayi 		else if (oct->chip_id == OCTEON_CN66XX)
908f21fb3edSRaghu Vatsavayi 			octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
909f21fb3edSRaghu Vatsavayi 					   VITESSE_PHY_GPIO_LOW);
910f21fb3edSRaghu Vatsavayi 		else
911f21fb3edSRaghu Vatsavayi 			return -EINVAL;
912f21fb3edSRaghu Vatsavayi 
913f21fb3edSRaghu Vatsavayi 		break;
914f21fb3edSRaghu Vatsavayi 
915f21fb3edSRaghu Vatsavayi 	case ETHTOOL_ID_INACTIVE:
916f21fb3edSRaghu Vatsavayi 		if (oct->chip_id == OCTEON_CN66XX) {
917f21fb3edSRaghu Vatsavayi 			octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
918f21fb3edSRaghu Vatsavayi 					   VITESSE_PHY_GPIO_DRIVEOFF);
919f21fb3edSRaghu Vatsavayi 		} else if (oct->chip_id == OCTEON_CN68XX) {
920f21fb3edSRaghu Vatsavayi 			/* Restore LED settings */
921f21fb3edSRaghu Vatsavayi 			ret = octnet_mdio45_access(lio, 1,
922f21fb3edSRaghu Vatsavayi 						   LIO68XX_LED_CTRL_ADDR,
923f21fb3edSRaghu Vatsavayi 						   &lio->led_ctrl_val);
924f21fb3edSRaghu Vatsavayi 			if (ret)
925f21fb3edSRaghu Vatsavayi 				return ret;
926f21fb3edSRaghu Vatsavayi 
927cbdb9777SDan Carpenter 			ret = octnet_mdio45_access(lio, 1,
928cbdb9777SDan Carpenter 						   LIO68XX_LED_BEACON_ADDR,
929f21fb3edSRaghu Vatsavayi 						   &lio->phy_beacon_val);
930f21fb3edSRaghu Vatsavayi 			if (ret)
931f21fb3edSRaghu Vatsavayi 				return ret;
932dc3abcbeSRaghu Vatsavayi 		} else if (oct->chip_id == OCTEON_CN23XX_PF_VID) {
933dc3abcbeSRaghu Vatsavayi 			octnet_id_active(netdev, LED_IDENTIFICATION_OFF);
934f21fb3edSRaghu Vatsavayi 
935dc3abcbeSRaghu Vatsavayi 			return 0;
936f21fb3edSRaghu Vatsavayi 		} else {
937f21fb3edSRaghu Vatsavayi 			return -EINVAL;
938f21fb3edSRaghu Vatsavayi 		}
939f21fb3edSRaghu Vatsavayi 		break;
940f21fb3edSRaghu Vatsavayi 
941f21fb3edSRaghu Vatsavayi 	default:
942f21fb3edSRaghu Vatsavayi 		return -EINVAL;
943f21fb3edSRaghu Vatsavayi 	}
944f21fb3edSRaghu Vatsavayi 
945f21fb3edSRaghu Vatsavayi 	return 0;
946f21fb3edSRaghu Vatsavayi }
947f21fb3edSRaghu Vatsavayi 
948f21fb3edSRaghu Vatsavayi static void
lio_ethtool_get_ringparam(struct net_device * netdev,struct ethtool_ringparam * ering,struct kernel_ethtool_ringparam * kernel_ering,struct netlink_ext_ack * extack)949f21fb3edSRaghu Vatsavayi lio_ethtool_get_ringparam(struct net_device *netdev,
95074624944SHao Chen 			  struct ethtool_ringparam *ering,
95174624944SHao Chen 			  struct kernel_ethtool_ringparam *kernel_ering,
95274624944SHao Chen 			  struct netlink_ext_ack *extack)
953f21fb3edSRaghu Vatsavayi {
954f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
955f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
956f21fb3edSRaghu Vatsavayi 	u32 tx_max_pending = 0, rx_max_pending = 0, tx_pending = 0,
957f21fb3edSRaghu Vatsavayi 	    rx_pending = 0;
958f21fb3edSRaghu Vatsavayi 
959d18ca7dfSIntiyaz Basha 	if (ifstate_check(lio, LIO_IFSTATE_RESETTING))
960d18ca7dfSIntiyaz Basha 		return;
961d18ca7dfSIntiyaz Basha 
962f21fb3edSRaghu Vatsavayi 	if (OCTEON_CN6XXX(oct)) {
96397a25326SRaghu Vatsavayi 		struct octeon_config *conf6x = CHIP_CONF(oct, cn6xxx);
964f21fb3edSRaghu Vatsavayi 
965f21fb3edSRaghu Vatsavayi 		tx_max_pending = CN6XXX_MAX_IQ_DESCRIPTORS;
966f21fb3edSRaghu Vatsavayi 		rx_max_pending = CN6XXX_MAX_OQ_DESCRIPTORS;
967f21fb3edSRaghu Vatsavayi 		rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf6x, lio->ifidx);
968f21fb3edSRaghu Vatsavayi 		tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf6x, lio->ifidx);
969c99c2872SIntiyaz Basha 	} else if (OCTEON_CN23XX_PF(oct) || OCTEON_CN23XX_VF(oct)) {
970dc3abcbeSRaghu Vatsavayi 		tx_max_pending = CN23XX_MAX_IQ_DESCRIPTORS;
971dc3abcbeSRaghu Vatsavayi 		rx_max_pending = CN23XX_MAX_OQ_DESCRIPTORS;
972c99c2872SIntiyaz Basha 		rx_pending = oct->droq[0]->max_count;
973c99c2872SIntiyaz Basha 		tx_pending = oct->instr_queue[0]->max_count;
974f21fb3edSRaghu Vatsavayi 	}
975f21fb3edSRaghu Vatsavayi 
976c99c2872SIntiyaz Basha 	ering->tx_pending = tx_pending;
977c99c2872SIntiyaz Basha 	ering->tx_max_pending = tx_max_pending;
978f21fb3edSRaghu Vatsavayi 	ering->rx_pending = rx_pending;
979f21fb3edSRaghu Vatsavayi 	ering->rx_max_pending = rx_max_pending;
980f21fb3edSRaghu Vatsavayi 	ering->rx_mini_pending = 0;
981f21fb3edSRaghu Vatsavayi 	ering->rx_jumbo_pending = 0;
982f21fb3edSRaghu Vatsavayi 	ering->rx_mini_max_pending = 0;
983f21fb3edSRaghu Vatsavayi 	ering->rx_jumbo_max_pending = 0;
984f21fb3edSRaghu Vatsavayi }
985f21fb3edSRaghu Vatsavayi 
lio_23xx_reconfigure_queue_count(struct lio * lio)986c33c9973SIntiyaz Basha static int lio_23xx_reconfigure_queue_count(struct lio *lio)
987c33c9973SIntiyaz Basha {
988c33c9973SIntiyaz Basha 	struct octeon_device *oct = lio->oct_dev;
98964fecd3eSFelix Manlunas 	u32 resp_size, data_size;
990c33c9973SIntiyaz Basha 	struct liquidio_if_cfg_resp *resp;
991c33c9973SIntiyaz Basha 	struct octeon_soft_command *sc;
992c33c9973SIntiyaz Basha 	union oct_nic_if_cfg if_cfg;
993c33c9973SIntiyaz Basha 	struct lio_version *vdata;
994c33c9973SIntiyaz Basha 	u32 ifidx_or_pfnum;
995c33c9973SIntiyaz Basha 	int retval;
996c33c9973SIntiyaz Basha 	int j;
997c33c9973SIntiyaz Basha 
998c33c9973SIntiyaz Basha 	resp_size = sizeof(struct liquidio_if_cfg_resp);
999c33c9973SIntiyaz Basha 	data_size = sizeof(struct lio_version);
1000c33c9973SIntiyaz Basha 	sc = (struct octeon_soft_command *)
1001c33c9973SIntiyaz Basha 		octeon_alloc_soft_command(oct, data_size,
100264fecd3eSFelix Manlunas 					  resp_size, 0);
1003c33c9973SIntiyaz Basha 	if (!sc) {
1004c33c9973SIntiyaz Basha 		dev_err(&oct->pci_dev->dev, "%s: Failed to allocate soft command\n",
1005c33c9973SIntiyaz Basha 			__func__);
1006c33c9973SIntiyaz Basha 		return -1;
1007c33c9973SIntiyaz Basha 	}
1008c33c9973SIntiyaz Basha 
1009c33c9973SIntiyaz Basha 	resp = (struct liquidio_if_cfg_resp *)sc->virtrptr;
1010c33c9973SIntiyaz Basha 	vdata = (struct lio_version *)sc->virtdptr;
1011c33c9973SIntiyaz Basha 
1012c33c9973SIntiyaz Basha 	vdata->major = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MAJOR_VERSION);
1013c33c9973SIntiyaz Basha 	vdata->minor = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MINOR_VERSION);
1014c33c9973SIntiyaz Basha 	vdata->micro = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MICRO_VERSION);
1015c33c9973SIntiyaz Basha 
1016c33c9973SIntiyaz Basha 	ifidx_or_pfnum = oct->pf_num;
1017c33c9973SIntiyaz Basha 
1018c33c9973SIntiyaz Basha 	if_cfg.u64 = 0;
1019c33c9973SIntiyaz Basha 	if_cfg.s.num_iqueues = oct->sriov_info.num_pf_rings;
1020c33c9973SIntiyaz Basha 	if_cfg.s.num_oqueues = oct->sriov_info.num_pf_rings;
1021c33c9973SIntiyaz Basha 	if_cfg.s.base_queue = oct->sriov_info.pf_srn;
1022c33c9973SIntiyaz Basha 	if_cfg.s.gmx_port_id = oct->pf_num;
1023c33c9973SIntiyaz Basha 
1024c33c9973SIntiyaz Basha 	sc->iq_no = 0;
1025c33c9973SIntiyaz Basha 	octeon_prepare_soft_command(oct, sc, OPCODE_NIC,
1026c33c9973SIntiyaz Basha 				    OPCODE_NIC_QCOUNT_UPDATE, 0,
1027c33c9973SIntiyaz Basha 				    if_cfg.u64, 0);
102864fecd3eSFelix Manlunas 
102964fecd3eSFelix Manlunas 	init_completion(&sc->complete);
103064fecd3eSFelix Manlunas 	sc->sc_status = OCTEON_REQUEST_PENDING;
1031c33c9973SIntiyaz Basha 
1032c33c9973SIntiyaz Basha 	retval = octeon_send_soft_command(oct, sc);
1033c33c9973SIntiyaz Basha 	if (retval == IQ_SEND_FAILED) {
1034c33c9973SIntiyaz Basha 		dev_err(&oct->pci_dev->dev,
103564fecd3eSFelix Manlunas 			"Sending iq/oq config failed status: %x\n",
1036c33c9973SIntiyaz Basha 			retval);
103764fecd3eSFelix Manlunas 		octeon_free_soft_command(oct, sc);
103864fecd3eSFelix Manlunas 		return -EIO;
1039c33c9973SIntiyaz Basha 	}
1040c33c9973SIntiyaz Basha 
104164fecd3eSFelix Manlunas 	retval = wait_for_sc_completion_timeout(oct, sc, 0);
104264fecd3eSFelix Manlunas 	if (retval)
104364fecd3eSFelix Manlunas 		return retval;
1044c33c9973SIntiyaz Basha 
1045c33c9973SIntiyaz Basha 	retval = resp->status;
1046c33c9973SIntiyaz Basha 	if (retval) {
104764fecd3eSFelix Manlunas 		dev_err(&oct->pci_dev->dev,
104864fecd3eSFelix Manlunas 			"iq/oq config failed: %x\n", retval);
104964fecd3eSFelix Manlunas 		WRITE_ONCE(sc->caller_is_done, true);
105064fecd3eSFelix Manlunas 		return -1;
1051c33c9973SIntiyaz Basha 	}
1052c33c9973SIntiyaz Basha 
1053c33c9973SIntiyaz Basha 	octeon_swap_8B_data((u64 *)(&resp->cfg_info),
1054c33c9973SIntiyaz Basha 			    (sizeof(struct liquidio_if_cfg_info)) >> 3);
1055c33c9973SIntiyaz Basha 
1056c33c9973SIntiyaz Basha 	lio->ifidx = ifidx_or_pfnum;
1057c33c9973SIntiyaz Basha 	lio->linfo.num_rxpciq = hweight64(resp->cfg_info.iqmask);
1058c33c9973SIntiyaz Basha 	lio->linfo.num_txpciq = hweight64(resp->cfg_info.iqmask);
1059c33c9973SIntiyaz Basha 	for (j = 0; j < lio->linfo.num_rxpciq; j++) {
1060c33c9973SIntiyaz Basha 		lio->linfo.rxpciq[j].u64 =
1061c33c9973SIntiyaz Basha 			resp->cfg_info.linfo.rxpciq[j].u64;
1062c33c9973SIntiyaz Basha 	}
1063c33c9973SIntiyaz Basha 
1064c33c9973SIntiyaz Basha 	for (j = 0; j < lio->linfo.num_txpciq; j++) {
1065c33c9973SIntiyaz Basha 		lio->linfo.txpciq[j].u64 =
1066c33c9973SIntiyaz Basha 			resp->cfg_info.linfo.txpciq[j].u64;
1067c33c9973SIntiyaz Basha 	}
1068c33c9973SIntiyaz Basha 
1069c33c9973SIntiyaz Basha 	lio->linfo.hw_addr = resp->cfg_info.linfo.hw_addr;
1070c33c9973SIntiyaz Basha 	lio->linfo.gmxport = resp->cfg_info.linfo.gmxport;
1071c33c9973SIntiyaz Basha 	lio->linfo.link.u64 = resp->cfg_info.linfo.link.u64;
1072c33c9973SIntiyaz Basha 	lio->txq = lio->linfo.txpciq[0].s.q_no;
1073c33c9973SIntiyaz Basha 	lio->rxq = lio->linfo.rxpciq[0].s.q_no;
1074c33c9973SIntiyaz Basha 
1075c33c9973SIntiyaz Basha 	dev_info(&oct->pci_dev->dev, "Queue count updated to %d\n",
1076c33c9973SIntiyaz Basha 		 lio->linfo.num_rxpciq);
1077c33c9973SIntiyaz Basha 
107864fecd3eSFelix Manlunas 	WRITE_ONCE(sc->caller_is_done, true);
107964fecd3eSFelix Manlunas 
1080c33c9973SIntiyaz Basha 	return 0;
1081c33c9973SIntiyaz Basha }
1082c33c9973SIntiyaz Basha 
lio_reset_queues(struct net_device * netdev,uint32_t num_qs)1083a82457f1SIntiyaz Basha static int lio_reset_queues(struct net_device *netdev, uint32_t num_qs)
1084d18ca7dfSIntiyaz Basha {
1085d18ca7dfSIntiyaz Basha 	struct lio *lio = GET_LIO(netdev);
1086d18ca7dfSIntiyaz Basha 	struct octeon_device *oct = lio->oct_dev;
1087c33c9973SIntiyaz Basha 	int i, queue_count_update = 0;
1088d18ca7dfSIntiyaz Basha 	struct napi_struct *napi, *n;
1089c33c9973SIntiyaz Basha 	int ret;
1090c33c9973SIntiyaz Basha 
1091c33c9973SIntiyaz Basha 	schedule_timeout_uninterruptible(msecs_to_jiffies(100));
1092d18ca7dfSIntiyaz Basha 
1093d18ca7dfSIntiyaz Basha 	if (wait_for_pending_requests(oct))
1094d18ca7dfSIntiyaz Basha 		dev_err(&oct->pci_dev->dev, "There were pending requests\n");
1095d18ca7dfSIntiyaz Basha 
1096d18ca7dfSIntiyaz Basha 	if (lio_wait_for_instr_fetch(oct))
1097d18ca7dfSIntiyaz Basha 		dev_err(&oct->pci_dev->dev, "IQ had pending instructions\n");
1098d18ca7dfSIntiyaz Basha 
1099d18ca7dfSIntiyaz Basha 	if (octeon_set_io_queues_off(oct)) {
1100c33c9973SIntiyaz Basha 		dev_err(&oct->pci_dev->dev, "Setting io queues off failed\n");
1101d18ca7dfSIntiyaz Basha 		return -1;
1102d18ca7dfSIntiyaz Basha 	}
1103d18ca7dfSIntiyaz Basha 
1104d18ca7dfSIntiyaz Basha 	/* Disable the input and output queues now. No more packets will
1105d18ca7dfSIntiyaz Basha 	 * arrive from Octeon.
1106d18ca7dfSIntiyaz Basha 	 */
1107d18ca7dfSIntiyaz Basha 	oct->fn_list.disable_io_queues(oct);
1108d18ca7dfSIntiyaz Basha 	/* Delete NAPI */
1109d18ca7dfSIntiyaz Basha 	list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list)
1110d18ca7dfSIntiyaz Basha 		netif_napi_del(napi);
1111d18ca7dfSIntiyaz Basha 
1112a82457f1SIntiyaz Basha 	if (num_qs != oct->num_iqs) {
1113c33c9973SIntiyaz Basha 		ret = netif_set_real_num_rx_queues(netdev, num_qs);
1114c33c9973SIntiyaz Basha 		if (ret) {
1115c33c9973SIntiyaz Basha 			dev_err(&oct->pci_dev->dev,
1116c33c9973SIntiyaz Basha 				"Setting real number rx failed\n");
1117c33c9973SIntiyaz Basha 			return ret;
1118c33c9973SIntiyaz Basha 		}
1119c33c9973SIntiyaz Basha 
1120c33c9973SIntiyaz Basha 		ret = netif_set_real_num_tx_queues(netdev, num_qs);
1121c33c9973SIntiyaz Basha 		if (ret) {
1122c33c9973SIntiyaz Basha 			dev_err(&oct->pci_dev->dev,
1123c33c9973SIntiyaz Basha 				"Setting real number tx failed\n");
1124c33c9973SIntiyaz Basha 			return ret;
1125c33c9973SIntiyaz Basha 		}
1126c33c9973SIntiyaz Basha 
1127c33c9973SIntiyaz Basha 		/* The value of queue_count_update decides whether it is the
1128c33c9973SIntiyaz Basha 		 * queue count or the descriptor count that is being
1129c33c9973SIntiyaz Basha 		 * re-configured.
1130c33c9973SIntiyaz Basha 		 */
1131c33c9973SIntiyaz Basha 		queue_count_update = 1;
1132c33c9973SIntiyaz Basha 	}
1133c33c9973SIntiyaz Basha 
1134c33c9973SIntiyaz Basha 	/* Re-configuration of queues can happen in two scenarios, SRIOV enabled
1135c33c9973SIntiyaz Basha 	 * and SRIOV disabled. Few things like recreating queue zero, resetting
1136c33c9973SIntiyaz Basha 	 * glists and IRQs are required for both. For the latter, some more
1137c33c9973SIntiyaz Basha 	 * steps like updating sriov_info for the octeon device need to be done.
1138c33c9973SIntiyaz Basha 	 */
1139c33c9973SIntiyaz Basha 	if (queue_count_update) {
11404b6e326bSIntiyaz Basha 		cleanup_rx_oom_poll_fn(netdev);
11414b6e326bSIntiyaz Basha 
1142c33c9973SIntiyaz Basha 		lio_delete_glists(lio);
1143c33c9973SIntiyaz Basha 
1144c33c9973SIntiyaz Basha 		/* Delete mbox for PF which is SRIOV disabled because sriov_info
1145c33c9973SIntiyaz Basha 		 * will be now changed.
1146c33c9973SIntiyaz Basha 		 */
1147c33c9973SIntiyaz Basha 		if ((OCTEON_CN23XX_PF(oct)) && !oct->sriov_info.sriov_enabled)
1148c33c9973SIntiyaz Basha 			oct->fn_list.free_mbox(oct);
1149a82457f1SIntiyaz Basha 	}
1150a82457f1SIntiyaz Basha 
1151d18ca7dfSIntiyaz Basha 	for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct); i++) {
1152d18ca7dfSIntiyaz Basha 		if (!(oct->io_qmask.oq & BIT_ULL(i)))
1153d18ca7dfSIntiyaz Basha 			continue;
1154d18ca7dfSIntiyaz Basha 		octeon_delete_droq(oct, i);
1155d18ca7dfSIntiyaz Basha 	}
1156d18ca7dfSIntiyaz Basha 
1157d18ca7dfSIntiyaz Basha 	for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct); i++) {
1158d18ca7dfSIntiyaz Basha 		if (!(oct->io_qmask.iq & BIT_ULL(i)))
1159d18ca7dfSIntiyaz Basha 			continue;
1160d18ca7dfSIntiyaz Basha 		octeon_delete_instr_queue(oct, i);
1161d18ca7dfSIntiyaz Basha 	}
1162d18ca7dfSIntiyaz Basha 
1163c33c9973SIntiyaz Basha 	if (queue_count_update) {
1164c33c9973SIntiyaz Basha 		/* For PF re-configure sriov related information */
1165c33c9973SIntiyaz Basha 		if ((OCTEON_CN23XX_PF(oct)) &&
1166c33c9973SIntiyaz Basha 		    !oct->sriov_info.sriov_enabled) {
1167c33c9973SIntiyaz Basha 			oct->sriov_info.num_pf_rings = num_qs;
1168c33c9973SIntiyaz Basha 			if (cn23xx_sriov_config(oct)) {
1169c33c9973SIntiyaz Basha 				dev_err(&oct->pci_dev->dev,
1170c33c9973SIntiyaz Basha 					"Queue reset aborted: SRIOV config failed\n");
1171c33c9973SIntiyaz Basha 				return -1;
1172c33c9973SIntiyaz Basha 			}
1173c33c9973SIntiyaz Basha 
1174c33c9973SIntiyaz Basha 			num_qs = oct->sriov_info.num_pf_rings;
1175c33c9973SIntiyaz Basha 		}
1176c33c9973SIntiyaz Basha 	}
1177c33c9973SIntiyaz Basha 
1178d18ca7dfSIntiyaz Basha 	if (oct->fn_list.setup_device_regs(oct)) {
1179d18ca7dfSIntiyaz Basha 		dev_err(&oct->pci_dev->dev, "Failed to configure device registers\n");
1180d18ca7dfSIntiyaz Basha 		return -1;
1181d18ca7dfSIntiyaz Basha 	}
1182d18ca7dfSIntiyaz Basha 
1183c33c9973SIntiyaz Basha 	/* The following are needed in case of queue count re-configuration and
1184c33c9973SIntiyaz Basha 	 * not for descriptor count re-configuration.
1185c33c9973SIntiyaz Basha 	 */
1186c33c9973SIntiyaz Basha 	if (queue_count_update) {
1187c33c9973SIntiyaz Basha 		if (octeon_setup_instr_queues(oct))
1188c33c9973SIntiyaz Basha 			return -1;
1189c33c9973SIntiyaz Basha 
1190c33c9973SIntiyaz Basha 		if (octeon_setup_output_queues(oct))
1191c33c9973SIntiyaz Basha 			return -1;
1192c33c9973SIntiyaz Basha 
1193c33c9973SIntiyaz Basha 		/* Recreating mbox for PF that is SRIOV disabled */
1194c33c9973SIntiyaz Basha 		if (OCTEON_CN23XX_PF(oct) && !oct->sriov_info.sriov_enabled) {
1195c33c9973SIntiyaz Basha 			if (oct->fn_list.setup_mbox(oct)) {
1196c33c9973SIntiyaz Basha 				dev_err(&oct->pci_dev->dev, "Mailbox setup failed\n");
1197c33c9973SIntiyaz Basha 				return -1;
1198c33c9973SIntiyaz Basha 			}
1199c33c9973SIntiyaz Basha 		}
1200c33c9973SIntiyaz Basha 
1201c33c9973SIntiyaz Basha 		/* Deleting and recreating IRQs whether the interface is SRIOV
1202c33c9973SIntiyaz Basha 		 * enabled or disabled.
1203c33c9973SIntiyaz Basha 		 */
1204c33c9973SIntiyaz Basha 		if (lio_irq_reallocate_irqs(oct, num_qs)) {
1205c33c9973SIntiyaz Basha 			dev_err(&oct->pci_dev->dev, "IRQs could not be allocated\n");
1206d18ca7dfSIntiyaz Basha 			return -1;
1207d18ca7dfSIntiyaz Basha 		}
1208d18ca7dfSIntiyaz Basha 
1209d18ca7dfSIntiyaz Basha 		/* Enable the input and output queues for this Octeon device */
1210d18ca7dfSIntiyaz Basha 		if (oct->fn_list.enable_io_queues(oct)) {
1211c33c9973SIntiyaz Basha 			dev_err(&oct->pci_dev->dev, "Failed to enable input/output queues\n");
1212d18ca7dfSIntiyaz Basha 			return -1;
1213d18ca7dfSIntiyaz Basha 		}
1214d18ca7dfSIntiyaz Basha 
1215c33c9973SIntiyaz Basha 		for (i = 0; i < oct->num_oqs; i++)
1216c33c9973SIntiyaz Basha 			writel(oct->droq[i]->max_count,
1217c33c9973SIntiyaz Basha 			       oct->droq[i]->pkts_credit_reg);
1218c33c9973SIntiyaz Basha 
1219c33c9973SIntiyaz Basha 		/* Informing firmware about the new queue count. It is required
1220c33c9973SIntiyaz Basha 		 * for firmware to allocate more number of queues than those at
1221c33c9973SIntiyaz Basha 		 * load time.
1222c33c9973SIntiyaz Basha 		 */
1223c33c9973SIntiyaz Basha 		if (OCTEON_CN23XX_PF(oct) && !oct->sriov_info.sriov_enabled) {
1224c33c9973SIntiyaz Basha 			if (lio_23xx_reconfigure_queue_count(lio))
1225a82457f1SIntiyaz Basha 				return -1;
1226c33c9973SIntiyaz Basha 		}
1227c33c9973SIntiyaz Basha 	}
1228c33c9973SIntiyaz Basha 
1229c33c9973SIntiyaz Basha 	/* Once firmware is aware of the new value, queues can be recreated */
1230c33c9973SIntiyaz Basha 	if (liquidio_setup_io_queues(oct, 0, num_qs, num_qs)) {
1231c33c9973SIntiyaz Basha 		dev_err(&oct->pci_dev->dev, "I/O queues creation failed\n");
1232c33c9973SIntiyaz Basha 		return -1;
1233c33c9973SIntiyaz Basha 	}
1234c33c9973SIntiyaz Basha 
1235c33c9973SIntiyaz Basha 	if (queue_count_update) {
1236c33c9973SIntiyaz Basha 		if (lio_setup_glists(oct, lio, num_qs)) {
1237c33c9973SIntiyaz Basha 			dev_err(&oct->pci_dev->dev, "Gather list allocation failed\n");
1238c33c9973SIntiyaz Basha 			return -1;
1239c33c9973SIntiyaz Basha 		}
1240c33c9973SIntiyaz Basha 
12414b6e326bSIntiyaz Basha 		if (setup_rx_oom_poll_fn(netdev)) {
12424b6e326bSIntiyaz Basha 			dev_err(&oct->pci_dev->dev, "lio_setup_rx_oom_poll_fn failed\n");
12434b6e326bSIntiyaz Basha 			return 1;
12444b6e326bSIntiyaz Basha 		}
12454b6e326bSIntiyaz Basha 
1246c33c9973SIntiyaz Basha 		/* Send firmware the information about new number of queues
1247c33c9973SIntiyaz Basha 		 * if the interface is a VF or a PF that is SRIOV enabled.
1248c33c9973SIntiyaz Basha 		 */
1249c33c9973SIntiyaz Basha 		if (oct->sriov_info.sriov_enabled || OCTEON_CN23XX_VF(oct))
1250c33c9973SIntiyaz Basha 			if (lio_send_queue_count_update(netdev, num_qs))
1251c33c9973SIntiyaz Basha 				return -1;
1252c33c9973SIntiyaz Basha 	}
1253a82457f1SIntiyaz Basha 
1254d18ca7dfSIntiyaz Basha 	return 0;
1255d18ca7dfSIntiyaz Basha }
1256d18ca7dfSIntiyaz Basha 
125774624944SHao Chen static int
lio_ethtool_set_ringparam(struct net_device * netdev,struct ethtool_ringparam * ering,struct kernel_ethtool_ringparam * kernel_ering,struct netlink_ext_ack * extack)125874624944SHao Chen lio_ethtool_set_ringparam(struct net_device *netdev,
125974624944SHao Chen 			  struct ethtool_ringparam *ering,
126074624944SHao Chen 			  struct kernel_ethtool_ringparam *kernel_ering,
126174624944SHao Chen 			  struct netlink_ext_ack *extack)
1262d18ca7dfSIntiyaz Basha {
1263d18ca7dfSIntiyaz Basha 	u32 rx_count, tx_count, rx_count_old, tx_count_old;
1264d18ca7dfSIntiyaz Basha 	struct lio *lio = GET_LIO(netdev);
1265d18ca7dfSIntiyaz Basha 	struct octeon_device *oct = lio->oct_dev;
1266d18ca7dfSIntiyaz Basha 	int stopped = 0;
1267d18ca7dfSIntiyaz Basha 
1268d18ca7dfSIntiyaz Basha 	if (!OCTEON_CN23XX_PF(oct) && !OCTEON_CN23XX_VF(oct))
1269d18ca7dfSIntiyaz Basha 		return -EINVAL;
1270d18ca7dfSIntiyaz Basha 
1271d18ca7dfSIntiyaz Basha 	if (ering->rx_mini_pending || ering->rx_jumbo_pending)
1272d18ca7dfSIntiyaz Basha 		return -EINVAL;
1273d18ca7dfSIntiyaz Basha 
1274d18ca7dfSIntiyaz Basha 	rx_count = clamp_t(u32, ering->rx_pending, CN23XX_MIN_OQ_DESCRIPTORS,
1275d18ca7dfSIntiyaz Basha 			   CN23XX_MAX_OQ_DESCRIPTORS);
1276d18ca7dfSIntiyaz Basha 	tx_count = clamp_t(u32, ering->tx_pending, CN23XX_MIN_IQ_DESCRIPTORS,
1277d18ca7dfSIntiyaz Basha 			   CN23XX_MAX_IQ_DESCRIPTORS);
1278d18ca7dfSIntiyaz Basha 
1279d18ca7dfSIntiyaz Basha 	rx_count_old = oct->droq[0]->max_count;
1280d18ca7dfSIntiyaz Basha 	tx_count_old = oct->instr_queue[0]->max_count;
1281d18ca7dfSIntiyaz Basha 
1282d18ca7dfSIntiyaz Basha 	if (rx_count == rx_count_old && tx_count == tx_count_old)
1283d18ca7dfSIntiyaz Basha 		return 0;
1284d18ca7dfSIntiyaz Basha 
1285d18ca7dfSIntiyaz Basha 	ifstate_set(lio, LIO_IFSTATE_RESETTING);
1286d18ca7dfSIntiyaz Basha 
1287d18ca7dfSIntiyaz Basha 	if (netif_running(netdev)) {
1288d18ca7dfSIntiyaz Basha 		netdev->netdev_ops->ndo_stop(netdev);
1289d18ca7dfSIntiyaz Basha 		stopped = 1;
1290d18ca7dfSIntiyaz Basha 	}
1291d18ca7dfSIntiyaz Basha 
1292d18ca7dfSIntiyaz Basha 	/* Change RX/TX DESCS  count */
1293d18ca7dfSIntiyaz Basha 	if (tx_count != tx_count_old)
1294d18ca7dfSIntiyaz Basha 		CFG_SET_NUM_TX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx,
1295d18ca7dfSIntiyaz Basha 					    tx_count);
1296d18ca7dfSIntiyaz Basha 	if (rx_count != rx_count_old)
1297d18ca7dfSIntiyaz Basha 		CFG_SET_NUM_RX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx,
1298d18ca7dfSIntiyaz Basha 					    rx_count);
1299d18ca7dfSIntiyaz Basha 
1300c33c9973SIntiyaz Basha 	if (lio_reset_queues(netdev, oct->num_iqs))
1301d18ca7dfSIntiyaz Basha 		goto err_lio_reset_queues;
1302d18ca7dfSIntiyaz Basha 
1303d18ca7dfSIntiyaz Basha 	if (stopped)
1304d18ca7dfSIntiyaz Basha 		netdev->netdev_ops->ndo_open(netdev);
1305d18ca7dfSIntiyaz Basha 
1306d18ca7dfSIntiyaz Basha 	ifstate_reset(lio, LIO_IFSTATE_RESETTING);
1307d18ca7dfSIntiyaz Basha 
1308d18ca7dfSIntiyaz Basha 	return 0;
1309d18ca7dfSIntiyaz Basha 
1310d18ca7dfSIntiyaz Basha err_lio_reset_queues:
1311d18ca7dfSIntiyaz Basha 	if (tx_count != tx_count_old)
1312d18ca7dfSIntiyaz Basha 		CFG_SET_NUM_TX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx,
1313d18ca7dfSIntiyaz Basha 					    tx_count_old);
1314d18ca7dfSIntiyaz Basha 	if (rx_count != rx_count_old)
1315d18ca7dfSIntiyaz Basha 		CFG_SET_NUM_RX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx,
1316d18ca7dfSIntiyaz Basha 					    rx_count_old);
1317d18ca7dfSIntiyaz Basha 	return -EINVAL;
1318d18ca7dfSIntiyaz Basha }
1319d18ca7dfSIntiyaz Basha 
lio_get_msglevel(struct net_device * netdev)1320f21fb3edSRaghu Vatsavayi static u32 lio_get_msglevel(struct net_device *netdev)
1321f21fb3edSRaghu Vatsavayi {
1322f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
1323f21fb3edSRaghu Vatsavayi 
1324f21fb3edSRaghu Vatsavayi 	return lio->msg_enable;
1325f21fb3edSRaghu Vatsavayi }
1326f21fb3edSRaghu Vatsavayi 
lio_set_msglevel(struct net_device * netdev,u32 msglvl)1327f21fb3edSRaghu Vatsavayi static void lio_set_msglevel(struct net_device *netdev, u32 msglvl)
1328f21fb3edSRaghu Vatsavayi {
1329f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
1330f21fb3edSRaghu Vatsavayi 
1331f21fb3edSRaghu Vatsavayi 	if ((msglvl ^ lio->msg_enable) & NETIF_MSG_HW) {
1332f21fb3edSRaghu Vatsavayi 		if (msglvl & NETIF_MSG_HW)
1333f21fb3edSRaghu Vatsavayi 			liquidio_set_feature(netdev,
13340cece6c5SRaghu Vatsavayi 					     OCTNET_CMD_VERBOSE_ENABLE, 0);
1335f21fb3edSRaghu Vatsavayi 		else
1336f21fb3edSRaghu Vatsavayi 			liquidio_set_feature(netdev,
13370cece6c5SRaghu Vatsavayi 					     OCTNET_CMD_VERBOSE_DISABLE, 0);
1338f21fb3edSRaghu Vatsavayi 	}
1339f21fb3edSRaghu Vatsavayi 
1340f21fb3edSRaghu Vatsavayi 	lio->msg_enable = msglvl;
1341f21fb3edSRaghu Vatsavayi }
1342f21fb3edSRaghu Vatsavayi 
lio_vf_set_msglevel(struct net_device * netdev,u32 msglvl)13437fa13653SDerek Chickles static void lio_vf_set_msglevel(struct net_device *netdev, u32 msglvl)
13447fa13653SDerek Chickles {
13457fa13653SDerek Chickles 	struct lio *lio = GET_LIO(netdev);
13467fa13653SDerek Chickles 
13477fa13653SDerek Chickles 	lio->msg_enable = msglvl;
13487fa13653SDerek Chickles }
13497fa13653SDerek Chickles 
1350f21fb3edSRaghu Vatsavayi static void
lio_get_pauseparam(struct net_device * netdev,struct ethtool_pauseparam * pause)1351f21fb3edSRaghu Vatsavayi lio_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
1352f21fb3edSRaghu Vatsavayi {
1353f21fb3edSRaghu Vatsavayi 	/* Notes: Not supporting any auto negotiation in these
1354f21fb3edSRaghu Vatsavayi 	 * drivers. Just report pause frame support.
1355f21fb3edSRaghu Vatsavayi 	 */
13561f164717SRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
13571f164717SRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
13581f164717SRaghu Vatsavayi 
13591f164717SRaghu Vatsavayi 	pause->autoneg = 0;
13601f164717SRaghu Vatsavayi 
13611f164717SRaghu Vatsavayi 	pause->tx_pause = oct->tx_pause;
13621f164717SRaghu Vatsavayi 	pause->rx_pause = oct->rx_pause;
1363f21fb3edSRaghu Vatsavayi }
1364f21fb3edSRaghu Vatsavayi 
136530136395SRaghu Vatsavayi static int
lio_set_pauseparam(struct net_device * netdev,struct ethtool_pauseparam * pause)136630136395SRaghu Vatsavayi lio_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
136730136395SRaghu Vatsavayi {
136830136395SRaghu Vatsavayi 	/* Notes: Not supporting any auto negotiation in these
136930136395SRaghu Vatsavayi 	 * drivers.
137030136395SRaghu Vatsavayi 	 */
137130136395SRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
137230136395SRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
137330136395SRaghu Vatsavayi 	struct octnic_ctrl_pkt nctrl;
137430136395SRaghu Vatsavayi 	struct oct_link_info *linfo = &lio->linfo;
137530136395SRaghu Vatsavayi 
137630136395SRaghu Vatsavayi 	int ret = 0;
137730136395SRaghu Vatsavayi 
137830136395SRaghu Vatsavayi 	if (oct->chip_id != OCTEON_CN23XX_PF_VID)
137930136395SRaghu Vatsavayi 		return -EINVAL;
138030136395SRaghu Vatsavayi 
138130136395SRaghu Vatsavayi 	if (linfo->link.s.duplex == 0) {
138230136395SRaghu Vatsavayi 		/*no flow control for half duplex*/
138330136395SRaghu Vatsavayi 		if (pause->rx_pause || pause->tx_pause)
138430136395SRaghu Vatsavayi 			return -EINVAL;
138530136395SRaghu Vatsavayi 	}
138630136395SRaghu Vatsavayi 
138730136395SRaghu Vatsavayi 	/*do not support autoneg of link flow control*/
138830136395SRaghu Vatsavayi 	if (pause->autoneg == AUTONEG_ENABLE)
138930136395SRaghu Vatsavayi 		return -EINVAL;
139030136395SRaghu Vatsavayi 
139130136395SRaghu Vatsavayi 	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
139230136395SRaghu Vatsavayi 
139330136395SRaghu Vatsavayi 	nctrl.ncmd.u64 = 0;
139430136395SRaghu Vatsavayi 	nctrl.ncmd.s.cmd = OCTNET_CMD_SET_FLOW_CTL;
139530136395SRaghu Vatsavayi 	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
139630136395SRaghu Vatsavayi 	nctrl.netpndev = (u64)netdev;
139730136395SRaghu Vatsavayi 	nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
139830136395SRaghu Vatsavayi 
139930136395SRaghu Vatsavayi 	if (pause->rx_pause) {
140030136395SRaghu Vatsavayi 		/*enable rx pause*/
140130136395SRaghu Vatsavayi 		nctrl.ncmd.s.param1 = 1;
140230136395SRaghu Vatsavayi 	} else {
140330136395SRaghu Vatsavayi 		/*disable rx pause*/
140430136395SRaghu Vatsavayi 		nctrl.ncmd.s.param1 = 0;
140530136395SRaghu Vatsavayi 	}
140630136395SRaghu Vatsavayi 
140730136395SRaghu Vatsavayi 	if (pause->tx_pause) {
140830136395SRaghu Vatsavayi 		/*enable tx pause*/
140930136395SRaghu Vatsavayi 		nctrl.ncmd.s.param2 = 1;
141030136395SRaghu Vatsavayi 	} else {
141130136395SRaghu Vatsavayi 		/*disable tx pause*/
141230136395SRaghu Vatsavayi 		nctrl.ncmd.s.param2 = 0;
141330136395SRaghu Vatsavayi 	}
141430136395SRaghu Vatsavayi 
141530136395SRaghu Vatsavayi 	ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
1416edd572d7SFelix Manlunas 	if (ret) {
1417edd572d7SFelix Manlunas 		dev_err(&oct->pci_dev->dev,
1418edd572d7SFelix Manlunas 			"Failed to set pause parameter, ret=%d\n", ret);
141930136395SRaghu Vatsavayi 		return -EINVAL;
142030136395SRaghu Vatsavayi 	}
142130136395SRaghu Vatsavayi 
142230136395SRaghu Vatsavayi 	oct->rx_pause = pause->rx_pause;
142330136395SRaghu Vatsavayi 	oct->tx_pause = pause->tx_pause;
142430136395SRaghu Vatsavayi 
142530136395SRaghu Vatsavayi 	return 0;
142630136395SRaghu Vatsavayi }
142730136395SRaghu Vatsavayi 
1428f21fb3edSRaghu Vatsavayi static void
lio_get_ethtool_stats(struct net_device * netdev,struct ethtool_stats * stats,u64 * data)1429f21fb3edSRaghu Vatsavayi lio_get_ethtool_stats(struct net_device *netdev,
1430a7d5a3dcSRaghu Vatsavayi 		      struct ethtool_stats *stats  __attribute__((unused)),
1431a7d5a3dcSRaghu Vatsavayi 		      u64 *data)
1432f21fb3edSRaghu Vatsavayi {
1433f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
1434f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
143580002347SPradeep Nalla 	struct rtnl_link_stats64 lstats;
1436f21fb3edSRaghu Vatsavayi 	int i = 0, j;
1437f21fb3edSRaghu Vatsavayi 
1438d18ca7dfSIntiyaz Basha 	if (ifstate_check(lio, LIO_IFSTATE_RESETTING))
1439d18ca7dfSIntiyaz Basha 		return;
1440d18ca7dfSIntiyaz Basha 
144180002347SPradeep Nalla 	netdev->netdev_ops->ndo_get_stats64(netdev, &lstats);
14421f164717SRaghu Vatsavayi 	/*sum of oct->droq[oq_no]->stats->rx_pkts_received */
144380002347SPradeep Nalla 	data[i++] = lstats.rx_packets;
14441f164717SRaghu Vatsavayi 	/*sum of oct->instr_queue[iq_no]->stats.tx_done */
144580002347SPradeep Nalla 	data[i++] = lstats.tx_packets;
14461f164717SRaghu Vatsavayi 	/*sum of oct->droq[oq_no]->stats->rx_bytes_received */
144780002347SPradeep Nalla 	data[i++] = lstats.rx_bytes;
14481f164717SRaghu Vatsavayi 	/*sum of oct->instr_queue[iq_no]->stats.tx_tot_bytes */
144980002347SPradeep Nalla 	data[i++] = lstats.tx_bytes;
145080002347SPradeep Nalla 	data[i++] = lstats.rx_errors +
1451897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromwire.fcs_err +
1452897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromwire.jabber_err +
1453897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromwire.l2_err +
145480002347SPradeep Nalla 			oct_dev->link_stats.fromwire.frame_err;
145580002347SPradeep Nalla 	data[i++] = lstats.tx_errors;
14561f164717SRaghu Vatsavayi 	/*sum of oct->droq[oq_no]->stats->rx_dropped +
14571f164717SRaghu Vatsavayi 	 *oct->droq[oq_no]->stats->dropped_nodispatch +
14581f164717SRaghu Vatsavayi 	 *oct->droq[oq_no]->stats->dropped_toomany +
14591f164717SRaghu Vatsavayi 	 *oct->droq[oq_no]->stats->dropped_nomem
14601f164717SRaghu Vatsavayi 	 */
146180002347SPradeep Nalla 	data[i++] = lstats.rx_dropped +
1462897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromwire.fifo_err +
1463897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromwire.dmac_drop +
1464897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromwire.red_drops +
1465897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromwire.fw_err_pko +
1466897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromwire.fw_err_link +
146780002347SPradeep Nalla 			oct_dev->link_stats.fromwire.fw_err_drop;
14681f164717SRaghu Vatsavayi 	/*sum of oct->instr_queue[iq_no]->stats.tx_dropped */
146980002347SPradeep Nalla 	data[i++] = lstats.tx_dropped +
1470897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromhost.max_collision_fail +
1471897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromhost.max_deferral_fail +
1472897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromhost.total_collisions +
1473897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromhost.fw_err_pko +
1474897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromhost.fw_err_link +
1475897ddc24SIntiyaz Basha 			oct_dev->link_stats.fromhost.fw_err_drop +
147680002347SPradeep Nalla 			oct_dev->link_stats.fromhost.fw_err_pki;
14771f164717SRaghu Vatsavayi 
14781f164717SRaghu Vatsavayi 	/* firmware tx stats */
14791f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[mdata->from_ifidx].
14801f164717SRaghu Vatsavayi 	 *fromhost.fw_total_sent
14811f164717SRaghu Vatsavayi 	 */
14821f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_total_sent);
14831f164717SRaghu Vatsavayi 	/*per_core_stats[i].link_stats[port].fromwire.fw_total_fwd */
14841f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_total_fwd);
14851f164717SRaghu Vatsavayi 	/*per_core_stats[j].link_stats[i].fromhost.fw_err_pko */
14861f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_pko);
1487741912c5SRick Farrington 	/*per_core_stats[j].link_stats[i].fromhost.fw_err_pki */
1488741912c5SRick Farrington 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_pki);
14891f164717SRaghu Vatsavayi 	/*per_core_stats[j].link_stats[i].fromhost.fw_err_link */
14901f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_link);
14911f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.
14921f164717SRaghu Vatsavayi 	 *fw_err_drop
14931f164717SRaghu Vatsavayi 	 */
14941f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_drop);
14951f164717SRaghu Vatsavayi 
14961f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.fw_tso */
14971f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tso);
14981f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.
14991f164717SRaghu Vatsavayi 	 *fw_tso_fwd
15001f164717SRaghu Vatsavayi 	 */
15011f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tso_fwd);
15021f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.
15031f164717SRaghu Vatsavayi 	 *fw_err_tso
15041f164717SRaghu Vatsavayi 	 */
15051f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_tso);
150601fb237aSRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.
150701fb237aSRaghu Vatsavayi 	 *fw_tx_vxlan
150801fb237aSRaghu Vatsavayi 	 */
150901fb237aSRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tx_vxlan);
15101f164717SRaghu Vatsavayi 
151180002347SPradeep Nalla 	/* Multicast packets sent by this port */
151280002347SPradeep Nalla 	data[i++] = oct_dev->link_stats.fromhost.fw_total_mcast_sent;
151380002347SPradeep Nalla 	data[i++] = oct_dev->link_stats.fromhost.fw_total_bcast_sent;
151480002347SPradeep Nalla 
15151f164717SRaghu Vatsavayi 	/* mac tx statistics */
15161f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT5 */
15171f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_pkts_sent);
15181f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT4 */
15191f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_bytes_sent);
15201f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT15 */
15211f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.mcast_pkts_sent);
15221f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT14 */
15231f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.bcast_pkts_sent);
15241f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT17 */
15251f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.ctl_sent);
15261f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT0 */
15271f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_collisions);
15281f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT3 */
15291f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.one_collision_sent);
15301f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT2 */
15311f164717SRaghu Vatsavayi 	data[i++] =
15321f164717SRaghu Vatsavayi 		CVM_CAST64(oct_dev->link_stats.fromhost.multi_collision_sent);
15331f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT0 */
15341f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.max_collision_fail);
15351f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT1 */
15361f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.max_deferral_fail);
15371f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT16 */
15381f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fifo_err);
15391f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_TX_STAT6 */
15401f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.runts);
15411f164717SRaghu Vatsavayi 
15421f164717SRaghu Vatsavayi 	/* RX firmware stats */
15431f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
15441f164717SRaghu Vatsavayi 	 *fw_total_rcvd
15451f164717SRaghu Vatsavayi 	 */
15461f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_rcvd);
15471f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
15481f164717SRaghu Vatsavayi 	 *fw_total_fwd
15491f164717SRaghu Vatsavayi 	 */
15501f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_fwd);
155180002347SPradeep Nalla 	/* Multicast packets received on this port */
155280002347SPradeep Nalla 	data[i++] = oct_dev->link_stats.fromwire.fw_total_mcast;
155380002347SPradeep Nalla 	data[i++] = oct_dev->link_stats.fromwire.fw_total_bcast;
15541f164717SRaghu Vatsavayi 	/*per_core_stats[core_id].link_stats[ifidx].fromwire.jabber_err */
15551f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.jabber_err);
15561f164717SRaghu Vatsavayi 	/*per_core_stats[core_id].link_stats[ifidx].fromwire.l2_err */
15571f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.l2_err);
15581f164717SRaghu Vatsavayi 	/*per_core_stats[core_id].link_stats[ifidx].fromwire.frame_err */
15591f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.frame_err);
15601f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
15611f164717SRaghu Vatsavayi 	 *fw_err_pko
15621f164717SRaghu Vatsavayi 	 */
15631f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_pko);
15641f164717SRaghu Vatsavayi 	/*per_core_stats[j].link_stats[i].fromwire.fw_err_link */
15651f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_link);
15661f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx].
15671f164717SRaghu Vatsavayi 	 *fromwire.fw_err_drop
15681f164717SRaghu Vatsavayi 	 */
15691f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_drop);
15701f164717SRaghu Vatsavayi 
157101fb237aSRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx].
157201fb237aSRaghu Vatsavayi 	 *fromwire.fw_rx_vxlan
157301fb237aSRaghu Vatsavayi 	 */
157401fb237aSRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_rx_vxlan);
157501fb237aSRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx].
157601fb237aSRaghu Vatsavayi 	 *fromwire.fw_rx_vxlan_err
157701fb237aSRaghu Vatsavayi 	 */
157801fb237aSRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_rx_vxlan_err);
157901fb237aSRaghu Vatsavayi 
15801f164717SRaghu Vatsavayi 	/* LRO */
15811f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
15821f164717SRaghu Vatsavayi 	 *fw_lro_pkts
15831f164717SRaghu Vatsavayi 	 */
15841f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_pkts);
15851f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
15861f164717SRaghu Vatsavayi 	 *fw_lro_octs
15871f164717SRaghu Vatsavayi 	 */
15881f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_octs);
15891f164717SRaghu Vatsavayi 	/*per_core_stats[j].link_stats[i].fromwire.fw_total_lro */
15901f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_lro);
15911f164717SRaghu Vatsavayi 	/*per_core_stats[j].link_stats[i].fromwire.fw_lro_aborts */
15921f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts);
15931f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
15941f164717SRaghu Vatsavayi 	 *fw_lro_aborts_port
15951f164717SRaghu Vatsavayi 	 */
15961f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_port);
15971f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
15981f164717SRaghu Vatsavayi 	 *fw_lro_aborts_seq
15991f164717SRaghu Vatsavayi 	 */
16001f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_seq);
16011f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
16021f164717SRaghu Vatsavayi 	 *fw_lro_aborts_tsval
16031f164717SRaghu Vatsavayi 	 */
16041f164717SRaghu Vatsavayi 	data[i++] =
16051f164717SRaghu Vatsavayi 		CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_tsval);
16061f164717SRaghu Vatsavayi 	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
16071f164717SRaghu Vatsavayi 	 *fw_lro_aborts_timer
16081f164717SRaghu Vatsavayi 	 */
16091f164717SRaghu Vatsavayi 	/* intrmod: packet forward rate */
16101f164717SRaghu Vatsavayi 	data[i++] =
16111f164717SRaghu Vatsavayi 		CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_timer);
16121f164717SRaghu Vatsavayi 	/*per_core_stats[j].link_stats[i].fromwire.fw_lro_aborts */
16131f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fwd_rate);
16141f164717SRaghu Vatsavayi 
16151f164717SRaghu Vatsavayi 	/* mac: link-level stats */
16161f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_RX_STAT0 */
16171f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_rcvd);
16181f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_RX_STAT1 */
16191f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.bytes_rcvd);
16201f164717SRaghu Vatsavayi 	/*CVMX_PKI_STATX_STAT5 */
16211f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_bcst);
16221f164717SRaghu Vatsavayi 	/*CVMX_PKI_STATX_STAT5 */
16231f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_mcst);
16241f164717SRaghu Vatsavayi 	/*wqe->word2.err_code or wqe->word2.err_level */
16251f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.runts);
16261f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_RX_STAT2 */
16271f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.ctl_rcvd);
16281f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_RX_STAT6 */
16291f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fifo_err);
16301f164717SRaghu Vatsavayi 	/*CVMX_BGXX_CMRX_RX_STAT4 */
16311f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.dmac_drop);
16321f164717SRaghu Vatsavayi 	/*wqe->word2.err_code or wqe->word2.err_level */
16331f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fcs_err);
16341f164717SRaghu Vatsavayi 	/*lio->link_changes*/
16351f164717SRaghu Vatsavayi 	data[i++] = CVM_CAST64(lio->link_changes);
16361f164717SRaghu Vatsavayi 
16371f164717SRaghu Vatsavayi 	for (j = 0; j < MAX_OCTEON_INSTR_QUEUES(oct_dev); j++) {
1638763185a3SRaghu Vatsavayi 		if (!(oct_dev->io_qmask.iq & BIT_ULL(j)))
1639f21fb3edSRaghu Vatsavayi 			continue;
16401f164717SRaghu Vatsavayi 		/*packets to network port*/
16411f164717SRaghu Vatsavayi 		/*# of packets tx to network */
16421f164717SRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_done);
16431f164717SRaghu Vatsavayi 		/*# of bytes tx to network */
1644f21fb3edSRaghu Vatsavayi 		data[i++] =
1645f21fb3edSRaghu Vatsavayi 			CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_tot_bytes);
16461f164717SRaghu Vatsavayi 		/*# of packets dropped */
16471f164717SRaghu Vatsavayi 		data[i++] =
16481f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_dropped);
16491f164717SRaghu Vatsavayi 		/*# of tx fails due to queue full */
16501f164717SRaghu Vatsavayi 		data[i++] =
16511f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_iq_busy);
16521f164717SRaghu Vatsavayi 		/*XXX gather entries sent */
16531f164717SRaghu Vatsavayi 		data[i++] =
16541f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->instr_queue[j]->stats.sgentry_sent);
16551f164717SRaghu Vatsavayi 
16561f164717SRaghu Vatsavayi 		/*instruction to firmware: data and control */
16571f164717SRaghu Vatsavayi 		/*# of instructions to the queue */
16581f164717SRaghu Vatsavayi 		data[i++] =
16591f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_posted);
16601f164717SRaghu Vatsavayi 		/*# of instructions processed */
16619ae122c6SSatanand Burla 		data[i++] = CVM_CAST64(
16629ae122c6SSatanand Burla 				oct_dev->instr_queue[j]->stats.instr_processed);
16631f164717SRaghu Vatsavayi 		/*# of instructions could not be processed */
16649ae122c6SSatanand Burla 		data[i++] = CVM_CAST64(
16659ae122c6SSatanand Burla 				oct_dev->instr_queue[j]->stats.instr_dropped);
16661f164717SRaghu Vatsavayi 		/*bytes sent through the queue */
16671f164717SRaghu Vatsavayi 		data[i++] =
16681f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->instr_queue[j]->stats.bytes_sent);
16691f164717SRaghu Vatsavayi 
16701f164717SRaghu Vatsavayi 		/*tso request*/
16711f164717SRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_gso);
167201fb237aSRaghu Vatsavayi 		/*vxlan request*/
167301fb237aSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_vxlan);
16741f164717SRaghu Vatsavayi 		/*txq restart*/
16751f164717SRaghu Vatsavayi 		data[i++] =
16761f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_restart);
1677f21fb3edSRaghu Vatsavayi 	}
1678f21fb3edSRaghu Vatsavayi 
16791f164717SRaghu Vatsavayi 	/* RX */
16801f164717SRaghu Vatsavayi 	for (j = 0; j < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); j++) {
1681763185a3SRaghu Vatsavayi 		if (!(oct_dev->io_qmask.oq & BIT_ULL(j)))
1682f21fb3edSRaghu Vatsavayi 			continue;
16831f164717SRaghu Vatsavayi 
16841f164717SRaghu Vatsavayi 		/*packets send to TCP/IP network stack */
16851f164717SRaghu Vatsavayi 		/*# of packets to network stack */
1686f21fb3edSRaghu Vatsavayi 		data[i++] =
1687f21fb3edSRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.rx_pkts_received);
16881f164717SRaghu Vatsavayi 		/*# of bytes to network stack */
1689f21fb3edSRaghu Vatsavayi 		data[i++] =
1690f21fb3edSRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.rx_bytes_received);
16911f164717SRaghu Vatsavayi 		/*# of packets dropped */
16921f164717SRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem +
16931f164717SRaghu Vatsavayi 				       oct_dev->droq[j]->stats.dropped_toomany +
16941f164717SRaghu Vatsavayi 				       oct_dev->droq[j]->stats.rx_dropped);
16951f164717SRaghu Vatsavayi 		data[i++] =
16961f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem);
16971f164717SRaghu Vatsavayi 		data[i++] =
16981f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.dropped_toomany);
1699f21fb3edSRaghu Vatsavayi 		data[i++] =
1700f21fb3edSRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.rx_dropped);
17011f164717SRaghu Vatsavayi 
17021f164717SRaghu Vatsavayi 		/*control and data path*/
17031f164717SRaghu Vatsavayi 		data[i++] =
17041f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.pkts_received);
17051f164717SRaghu Vatsavayi 		data[i++] =
17061f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.bytes_received);
17071f164717SRaghu Vatsavayi 		data[i++] =
17081f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.dropped_nodispatch);
170901fb237aSRaghu Vatsavayi 
171001fb237aSRaghu Vatsavayi 		data[i++] =
171101fb237aSRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.rx_vxlan);
17121f164717SRaghu Vatsavayi 		data[i++] =
17131f164717SRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.rx_alloc_failure);
1714f21fb3edSRaghu Vatsavayi 	}
1715f21fb3edSRaghu Vatsavayi }
1716f21fb3edSRaghu Vatsavayi 
lio_vf_get_ethtool_stats(struct net_device * netdev,struct ethtool_stats * stats,u64 * data)1717d8ab848cSRaghu Vatsavayi static void lio_vf_get_ethtool_stats(struct net_device *netdev,
1718d8ab848cSRaghu Vatsavayi 				     struct ethtool_stats *stats
1719d8ab848cSRaghu Vatsavayi 				     __attribute__((unused)),
1720d8ab848cSRaghu Vatsavayi 				     u64 *data)
1721d8ab848cSRaghu Vatsavayi {
172280002347SPradeep Nalla 	struct rtnl_link_stats64 lstats;
1723d8ab848cSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
1724d8ab848cSRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
1725d8ab848cSRaghu Vatsavayi 	int i = 0, j, vj;
1726d8ab848cSRaghu Vatsavayi 
1727d18ca7dfSIntiyaz Basha 	if (ifstate_check(lio, LIO_IFSTATE_RESETTING))
1728d18ca7dfSIntiyaz Basha 		return;
1729d18ca7dfSIntiyaz Basha 
173080002347SPradeep Nalla 	netdev->netdev_ops->ndo_get_stats64(netdev, &lstats);
1731d8ab848cSRaghu Vatsavayi 	/* sum of oct->droq[oq_no]->stats->rx_pkts_received */
173280002347SPradeep Nalla 	data[i++] = lstats.rx_packets;
1733d8ab848cSRaghu Vatsavayi 	/* sum of oct->instr_queue[iq_no]->stats.tx_done */
173480002347SPradeep Nalla 	data[i++] = lstats.tx_packets;
1735d8ab848cSRaghu Vatsavayi 	/* sum of oct->droq[oq_no]->stats->rx_bytes_received */
173680002347SPradeep Nalla 	data[i++] = lstats.rx_bytes;
1737d8ab848cSRaghu Vatsavayi 	/* sum of oct->instr_queue[iq_no]->stats.tx_tot_bytes */
173880002347SPradeep Nalla 	data[i++] = lstats.tx_bytes;
173980002347SPradeep Nalla 	data[i++] = lstats.rx_errors;
174080002347SPradeep Nalla 	data[i++] = lstats.tx_errors;
1741d8ab848cSRaghu Vatsavayi 	 /* sum of oct->droq[oq_no]->stats->rx_dropped +
1742d8ab848cSRaghu Vatsavayi 	  * oct->droq[oq_no]->stats->dropped_nodispatch +
1743d8ab848cSRaghu Vatsavayi 	  * oct->droq[oq_no]->stats->dropped_toomany +
1744d8ab848cSRaghu Vatsavayi 	  * oct->droq[oq_no]->stats->dropped_nomem
1745d8ab848cSRaghu Vatsavayi 	  */
174680002347SPradeep Nalla 	data[i++] = lstats.rx_dropped;
1747d8ab848cSRaghu Vatsavayi 	/* sum of oct->instr_queue[iq_no]->stats.tx_dropped */
174848875222SWeilin Chang 	data[i++] = lstats.tx_dropped +
174948875222SWeilin Chang 		oct_dev->link_stats.fromhost.fw_err_drop;
175080002347SPradeep Nalla 
175180002347SPradeep Nalla 	data[i++] = oct_dev->link_stats.fromwire.fw_total_mcast;
175280002347SPradeep Nalla 	data[i++] = oct_dev->link_stats.fromhost.fw_total_mcast_sent;
175380002347SPradeep Nalla 	data[i++] = oct_dev->link_stats.fromwire.fw_total_bcast;
175480002347SPradeep Nalla 	data[i++] = oct_dev->link_stats.fromhost.fw_total_bcast_sent;
175580002347SPradeep Nalla 
1756d8ab848cSRaghu Vatsavayi 	/* lio->link_changes */
1757d8ab848cSRaghu Vatsavayi 	data[i++] = CVM_CAST64(lio->link_changes);
1758d8ab848cSRaghu Vatsavayi 
1759a82457f1SIntiyaz Basha 	for (vj = 0; vj < oct_dev->num_iqs; vj++) {
1760d8ab848cSRaghu Vatsavayi 		j = lio->linfo.txpciq[vj].s.q_no;
1761d8ab848cSRaghu Vatsavayi 
1762d8ab848cSRaghu Vatsavayi 		/* packets to network port */
1763d8ab848cSRaghu Vatsavayi 		/* # of packets tx to network */
1764d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_done);
1765d8ab848cSRaghu Vatsavayi 		 /* # of bytes tx to network */
1766d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(
1767d8ab848cSRaghu Vatsavayi 				oct_dev->instr_queue[j]->stats.tx_tot_bytes);
1768d8ab848cSRaghu Vatsavayi 		/* # of packets dropped */
1769d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(
1770d8ab848cSRaghu Vatsavayi 				oct_dev->instr_queue[j]->stats.tx_dropped);
1771d8ab848cSRaghu Vatsavayi 		/* # of tx fails due to queue full */
1772d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(
1773d8ab848cSRaghu Vatsavayi 				oct_dev->instr_queue[j]->stats.tx_iq_busy);
1774d8ab848cSRaghu Vatsavayi 		/* XXX gather entries sent */
1775d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(
1776d8ab848cSRaghu Vatsavayi 				oct_dev->instr_queue[j]->stats.sgentry_sent);
1777d8ab848cSRaghu Vatsavayi 
1778d8ab848cSRaghu Vatsavayi 		/* instruction to firmware: data and control */
1779d8ab848cSRaghu Vatsavayi 		/* # of instructions to the queue */
1780d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(
1781d8ab848cSRaghu Vatsavayi 				oct_dev->instr_queue[j]->stats.instr_posted);
1782d8ab848cSRaghu Vatsavayi 		/* # of instructions processed */
1783d8ab848cSRaghu Vatsavayi 		data[i++] =
1784d8ab848cSRaghu Vatsavayi 		    CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_processed);
1785d8ab848cSRaghu Vatsavayi 		/* # of instructions could not be processed */
1786d8ab848cSRaghu Vatsavayi 		data[i++] =
1787d8ab848cSRaghu Vatsavayi 		    CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_dropped);
1788d8ab848cSRaghu Vatsavayi 		/* bytes sent through the queue */
1789d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(
1790d8ab848cSRaghu Vatsavayi 				oct_dev->instr_queue[j]->stats.bytes_sent);
1791d8ab848cSRaghu Vatsavayi 		/* tso request */
1792d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_gso);
1793d8ab848cSRaghu Vatsavayi 		/* vxlan request */
1794d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_vxlan);
1795d8ab848cSRaghu Vatsavayi 		/* txq restart */
1796d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(
1797d8ab848cSRaghu Vatsavayi 				oct_dev->instr_queue[j]->stats.tx_restart);
1798d8ab848cSRaghu Vatsavayi 	}
1799d8ab848cSRaghu Vatsavayi 
1800d8ab848cSRaghu Vatsavayi 	/* RX */
1801a82457f1SIntiyaz Basha 	for (vj = 0; vj < oct_dev->num_oqs; vj++) {
1802d8ab848cSRaghu Vatsavayi 		j = lio->linfo.rxpciq[vj].s.q_no;
1803d8ab848cSRaghu Vatsavayi 
1804d8ab848cSRaghu Vatsavayi 		/* packets send to TCP/IP network stack */
1805d8ab848cSRaghu Vatsavayi 		/* # of packets to network stack */
1806d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(
1807d8ab848cSRaghu Vatsavayi 				oct_dev->droq[j]->stats.rx_pkts_received);
1808d8ab848cSRaghu Vatsavayi 		/* # of bytes to network stack */
1809d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(
1810d8ab848cSRaghu Vatsavayi 				oct_dev->droq[j]->stats.rx_bytes_received);
1811d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem +
1812d8ab848cSRaghu Vatsavayi 				       oct_dev->droq[j]->stats.dropped_toomany +
1813d8ab848cSRaghu Vatsavayi 				       oct_dev->droq[j]->stats.rx_dropped);
1814d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem);
1815d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_toomany);
1816d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.rx_dropped);
1817d8ab848cSRaghu Vatsavayi 
1818d8ab848cSRaghu Vatsavayi 		/* control and data path */
1819d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.pkts_received);
1820d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.bytes_received);
1821d8ab848cSRaghu Vatsavayi 		data[i++] =
1822d8ab848cSRaghu Vatsavayi 			CVM_CAST64(oct_dev->droq[j]->stats.dropped_nodispatch);
1823d8ab848cSRaghu Vatsavayi 
1824d8ab848cSRaghu Vatsavayi 		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.rx_vxlan);
1825d8ab848cSRaghu Vatsavayi 		data[i++] =
1826d8ab848cSRaghu Vatsavayi 		    CVM_CAST64(oct_dev->droq[j]->stats.rx_alloc_failure);
1827d8ab848cSRaghu Vatsavayi 	}
1828d8ab848cSRaghu Vatsavayi }
1829d8ab848cSRaghu Vatsavayi 
lio_get_priv_flags_strings(struct lio * lio,u8 * data)183030136395SRaghu Vatsavayi static void lio_get_priv_flags_strings(struct lio *lio, u8 *data)
183130136395SRaghu Vatsavayi {
183230136395SRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
183330136395SRaghu Vatsavayi 	int i;
183430136395SRaghu Vatsavayi 
183530136395SRaghu Vatsavayi 	switch (oct_dev->chip_id) {
183630136395SRaghu Vatsavayi 	case OCTEON_CN23XX_PF_VID:
1837d8ab848cSRaghu Vatsavayi 	case OCTEON_CN23XX_VF_VID:
183830136395SRaghu Vatsavayi 		for (i = 0; i < ARRAY_SIZE(oct_priv_flags_strings); i++) {
183930136395SRaghu Vatsavayi 			sprintf(data, "%s", oct_priv_flags_strings[i]);
184030136395SRaghu Vatsavayi 			data += ETH_GSTRING_LEN;
184130136395SRaghu Vatsavayi 		}
184230136395SRaghu Vatsavayi 		break;
184330136395SRaghu Vatsavayi 	case OCTEON_CN68XX:
184430136395SRaghu Vatsavayi 	case OCTEON_CN66XX:
184530136395SRaghu Vatsavayi 		break;
184630136395SRaghu Vatsavayi 	default:
184730136395SRaghu Vatsavayi 		netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n");
184830136395SRaghu Vatsavayi 		break;
184930136395SRaghu Vatsavayi 	}
185030136395SRaghu Vatsavayi }
185130136395SRaghu Vatsavayi 
lio_get_strings(struct net_device * netdev,u32 stringset,u8 * data)1852f21fb3edSRaghu Vatsavayi static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
1853f21fb3edSRaghu Vatsavayi {
1854f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
1855f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
1856f21fb3edSRaghu Vatsavayi 	int num_iq_stats, num_oq_stats, i, j;
18571f164717SRaghu Vatsavayi 	int num_stats;
18581f164717SRaghu Vatsavayi 
18591f164717SRaghu Vatsavayi 	switch (stringset) {
18601f164717SRaghu Vatsavayi 	case ETH_SS_STATS:
18611f164717SRaghu Vatsavayi 		num_stats = ARRAY_SIZE(oct_stats_strings);
18621f164717SRaghu Vatsavayi 		for (j = 0; j < num_stats; j++) {
18631f164717SRaghu Vatsavayi 			sprintf(data, "%s", oct_stats_strings[j]);
18641f164717SRaghu Vatsavayi 			data += ETH_GSTRING_LEN;
18651f164717SRaghu Vatsavayi 		}
1866f21fb3edSRaghu Vatsavayi 
1867f21fb3edSRaghu Vatsavayi 		num_iq_stats = ARRAY_SIZE(oct_iq_stats_strings);
18681f164717SRaghu Vatsavayi 		for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct_dev); i++) {
1869763185a3SRaghu Vatsavayi 			if (!(oct_dev->io_qmask.iq & BIT_ULL(i)))
1870f21fb3edSRaghu Vatsavayi 				continue;
1871f21fb3edSRaghu Vatsavayi 			for (j = 0; j < num_iq_stats; j++) {
18721f164717SRaghu Vatsavayi 				sprintf(data, "tx-%d-%s", i,
18731f164717SRaghu Vatsavayi 					oct_iq_stats_strings[j]);
1874f21fb3edSRaghu Vatsavayi 				data += ETH_GSTRING_LEN;
1875f21fb3edSRaghu Vatsavayi 			}
1876f21fb3edSRaghu Vatsavayi 		}
1877f21fb3edSRaghu Vatsavayi 
1878f21fb3edSRaghu Vatsavayi 		num_oq_stats = ARRAY_SIZE(oct_droq_stats_strings);
18791f164717SRaghu Vatsavayi 		for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); i++) {
1880763185a3SRaghu Vatsavayi 			if (!(oct_dev->io_qmask.oq & BIT_ULL(i)))
1881f21fb3edSRaghu Vatsavayi 				continue;
1882f21fb3edSRaghu Vatsavayi 			for (j = 0; j < num_oq_stats; j++) {
18831f164717SRaghu Vatsavayi 				sprintf(data, "rx-%d-%s", i,
18841f164717SRaghu Vatsavayi 					oct_droq_stats_strings[j]);
1885f21fb3edSRaghu Vatsavayi 				data += ETH_GSTRING_LEN;
1886f21fb3edSRaghu Vatsavayi 			}
1887f21fb3edSRaghu Vatsavayi 		}
18881f164717SRaghu Vatsavayi 		break;
18891f164717SRaghu Vatsavayi 
189030136395SRaghu Vatsavayi 	case ETH_SS_PRIV_FLAGS:
189130136395SRaghu Vatsavayi 		lio_get_priv_flags_strings(lio, data);
189230136395SRaghu Vatsavayi 		break;
18931f164717SRaghu Vatsavayi 	default:
18941f164717SRaghu Vatsavayi 		netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n");
18951f164717SRaghu Vatsavayi 		break;
18961f164717SRaghu Vatsavayi 	}
1897f21fb3edSRaghu Vatsavayi }
1898f21fb3edSRaghu Vatsavayi 
lio_vf_get_strings(struct net_device * netdev,u32 stringset,u8 * data)1899d8ab848cSRaghu Vatsavayi static void lio_vf_get_strings(struct net_device *netdev, u32 stringset,
1900d8ab848cSRaghu Vatsavayi 			       u8 *data)
1901d8ab848cSRaghu Vatsavayi {
1902d8ab848cSRaghu Vatsavayi 	int num_iq_stats, num_oq_stats, i, j;
1903d8ab848cSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
1904d8ab848cSRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
1905d8ab848cSRaghu Vatsavayi 	int num_stats;
1906d8ab848cSRaghu Vatsavayi 
1907d8ab848cSRaghu Vatsavayi 	switch (stringset) {
1908d8ab848cSRaghu Vatsavayi 	case ETH_SS_STATS:
1909d8ab848cSRaghu Vatsavayi 		num_stats = ARRAY_SIZE(oct_vf_stats_strings);
1910d8ab848cSRaghu Vatsavayi 		for (j = 0; j < num_stats; j++) {
1911d8ab848cSRaghu Vatsavayi 			sprintf(data, "%s", oct_vf_stats_strings[j]);
1912d8ab848cSRaghu Vatsavayi 			data += ETH_GSTRING_LEN;
1913d8ab848cSRaghu Vatsavayi 		}
1914d8ab848cSRaghu Vatsavayi 
1915d8ab848cSRaghu Vatsavayi 		num_iq_stats = ARRAY_SIZE(oct_iq_stats_strings);
1916d8ab848cSRaghu Vatsavayi 		for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct_dev); i++) {
1917d8ab848cSRaghu Vatsavayi 			if (!(oct_dev->io_qmask.iq & BIT_ULL(i)))
1918d8ab848cSRaghu Vatsavayi 				continue;
1919d8ab848cSRaghu Vatsavayi 			for (j = 0; j < num_iq_stats; j++) {
1920d8ab848cSRaghu Vatsavayi 				sprintf(data, "tx-%d-%s", i,
1921d8ab848cSRaghu Vatsavayi 					oct_iq_stats_strings[j]);
1922d8ab848cSRaghu Vatsavayi 				data += ETH_GSTRING_LEN;
1923d8ab848cSRaghu Vatsavayi 			}
1924d8ab848cSRaghu Vatsavayi 		}
1925d8ab848cSRaghu Vatsavayi 
1926d8ab848cSRaghu Vatsavayi 		num_oq_stats = ARRAY_SIZE(oct_droq_stats_strings);
1927d8ab848cSRaghu Vatsavayi 		for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); i++) {
1928d8ab848cSRaghu Vatsavayi 			if (!(oct_dev->io_qmask.oq & BIT_ULL(i)))
1929d8ab848cSRaghu Vatsavayi 				continue;
1930d8ab848cSRaghu Vatsavayi 			for (j = 0; j < num_oq_stats; j++) {
1931d8ab848cSRaghu Vatsavayi 				sprintf(data, "rx-%d-%s", i,
1932d8ab848cSRaghu Vatsavayi 					oct_droq_stats_strings[j]);
1933d8ab848cSRaghu Vatsavayi 				data += ETH_GSTRING_LEN;
1934d8ab848cSRaghu Vatsavayi 			}
1935d8ab848cSRaghu Vatsavayi 		}
1936d8ab848cSRaghu Vatsavayi 		break;
1937d8ab848cSRaghu Vatsavayi 
1938d8ab848cSRaghu Vatsavayi 	case ETH_SS_PRIV_FLAGS:
1939d8ab848cSRaghu Vatsavayi 		lio_get_priv_flags_strings(lio, data);
1940d8ab848cSRaghu Vatsavayi 		break;
1941d8ab848cSRaghu Vatsavayi 	default:
1942d8ab848cSRaghu Vatsavayi 		netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n");
1943d8ab848cSRaghu Vatsavayi 		break;
1944d8ab848cSRaghu Vatsavayi 	}
1945d8ab848cSRaghu Vatsavayi }
1946d8ab848cSRaghu Vatsavayi 
lio_get_priv_flags_ss_count(struct lio * lio)194730136395SRaghu Vatsavayi static int lio_get_priv_flags_ss_count(struct lio *lio)
194830136395SRaghu Vatsavayi {
194930136395SRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
195030136395SRaghu Vatsavayi 
195130136395SRaghu Vatsavayi 	switch (oct_dev->chip_id) {
195230136395SRaghu Vatsavayi 	case OCTEON_CN23XX_PF_VID:
1953d8ab848cSRaghu Vatsavayi 	case OCTEON_CN23XX_VF_VID:
195430136395SRaghu Vatsavayi 		return ARRAY_SIZE(oct_priv_flags_strings);
195530136395SRaghu Vatsavayi 	case OCTEON_CN68XX:
195630136395SRaghu Vatsavayi 	case OCTEON_CN66XX:
195730136395SRaghu Vatsavayi 		return -EOPNOTSUPP;
195830136395SRaghu Vatsavayi 	default:
195930136395SRaghu Vatsavayi 		netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n");
196030136395SRaghu Vatsavayi 		return -EOPNOTSUPP;
196130136395SRaghu Vatsavayi 	}
196230136395SRaghu Vatsavayi }
196330136395SRaghu Vatsavayi 
lio_get_sset_count(struct net_device * netdev,int sset)1964f21fb3edSRaghu Vatsavayi static int lio_get_sset_count(struct net_device *netdev, int sset)
1965f21fb3edSRaghu Vatsavayi {
1966f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
1967f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
1968f21fb3edSRaghu Vatsavayi 
19691f164717SRaghu Vatsavayi 	switch (sset) {
19701f164717SRaghu Vatsavayi 	case ETH_SS_STATS:
19711f164717SRaghu Vatsavayi 		return (ARRAY_SIZE(oct_stats_strings) +
19721f164717SRaghu Vatsavayi 			ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs +
19731f164717SRaghu Vatsavayi 			ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs);
197430136395SRaghu Vatsavayi 	case ETH_SS_PRIV_FLAGS:
197530136395SRaghu Vatsavayi 		return lio_get_priv_flags_ss_count(lio);
19761f164717SRaghu Vatsavayi 	default:
19771f164717SRaghu Vatsavayi 		return -EOPNOTSUPP;
19781f164717SRaghu Vatsavayi 	}
1979f21fb3edSRaghu Vatsavayi }
1980f21fb3edSRaghu Vatsavayi 
lio_vf_get_sset_count(struct net_device * netdev,int sset)1981d8ab848cSRaghu Vatsavayi static int lio_vf_get_sset_count(struct net_device *netdev, int sset)
1982d8ab848cSRaghu Vatsavayi {
1983d8ab848cSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
1984d8ab848cSRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
1985d8ab848cSRaghu Vatsavayi 
1986d8ab848cSRaghu Vatsavayi 	switch (sset) {
1987d8ab848cSRaghu Vatsavayi 	case ETH_SS_STATS:
1988d8ab848cSRaghu Vatsavayi 		return (ARRAY_SIZE(oct_vf_stats_strings) +
1989d8ab848cSRaghu Vatsavayi 			ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs +
1990d8ab848cSRaghu Vatsavayi 			ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs);
1991d8ab848cSRaghu Vatsavayi 	case ETH_SS_PRIV_FLAGS:
1992d8ab848cSRaghu Vatsavayi 		return lio_get_priv_flags_ss_count(lio);
1993d8ab848cSRaghu Vatsavayi 	default:
1994d8ab848cSRaghu Vatsavayi 		return -EOPNOTSUPP;
1995d8ab848cSRaghu Vatsavayi 	}
1996d8ab848cSRaghu Vatsavayi }
1997d8ab848cSRaghu Vatsavayi 
199850c0add5SPrasad Kanneganti /*  get interrupt moderation parameters */
octnet_get_intrmod_cfg(struct lio * lio,struct oct_intrmod_cfg * intr_cfg)199950c0add5SPrasad Kanneganti static int octnet_get_intrmod_cfg(struct lio *lio,
200050c0add5SPrasad Kanneganti 				  struct oct_intrmod_cfg *intr_cfg)
200150c0add5SPrasad Kanneganti {
200250c0add5SPrasad Kanneganti 	struct octeon_soft_command *sc;
200350c0add5SPrasad Kanneganti 	struct oct_intrmod_resp *resp;
200450c0add5SPrasad Kanneganti 	int retval;
200550c0add5SPrasad Kanneganti 	struct octeon_device *oct_dev = lio->oct_dev;
200650c0add5SPrasad Kanneganti 
200750c0add5SPrasad Kanneganti 	/* Alloc soft command */
200850c0add5SPrasad Kanneganti 	sc = (struct octeon_soft_command *)
200950c0add5SPrasad Kanneganti 		octeon_alloc_soft_command(oct_dev,
201050c0add5SPrasad Kanneganti 					  0,
201164fecd3eSFelix Manlunas 					  sizeof(struct oct_intrmod_resp), 0);
201250c0add5SPrasad Kanneganti 
201350c0add5SPrasad Kanneganti 	if (!sc)
201450c0add5SPrasad Kanneganti 		return -ENOMEM;
201550c0add5SPrasad Kanneganti 
201650c0add5SPrasad Kanneganti 	resp = (struct oct_intrmod_resp *)sc->virtrptr;
201750c0add5SPrasad Kanneganti 	memset(resp, 0, sizeof(struct oct_intrmod_resp));
201850c0add5SPrasad Kanneganti 
201950c0add5SPrasad Kanneganti 	sc->iq_no = lio->linfo.txpciq[0].s.q_no;
202050c0add5SPrasad Kanneganti 
202150c0add5SPrasad Kanneganti 	octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC,
202250c0add5SPrasad Kanneganti 				    OPCODE_NIC_INTRMOD_PARAMS, 0, 0, 0);
202350c0add5SPrasad Kanneganti 
202464fecd3eSFelix Manlunas 	init_completion(&sc->complete);
202564fecd3eSFelix Manlunas 	sc->sc_status = OCTEON_REQUEST_PENDING;
202650c0add5SPrasad Kanneganti 
202750c0add5SPrasad Kanneganti 	retval = octeon_send_soft_command(oct_dev, sc);
202850c0add5SPrasad Kanneganti 	if (retval == IQ_SEND_FAILED) {
202950c0add5SPrasad Kanneganti 		octeon_free_soft_command(oct_dev, sc);
203050c0add5SPrasad Kanneganti 		return -EINVAL;
203150c0add5SPrasad Kanneganti 	}
203250c0add5SPrasad Kanneganti 
203350c0add5SPrasad Kanneganti 	/* Sleep on a wait queue till the cond flag indicates that the
203450c0add5SPrasad Kanneganti 	 * response arrived or timed-out.
203550c0add5SPrasad Kanneganti 	 */
203664fecd3eSFelix Manlunas 	retval = wait_for_sc_completion_timeout(oct_dev, sc, 0);
203764fecd3eSFelix Manlunas 	if (retval)
203864fecd3eSFelix Manlunas 		return -ENODEV;
203950c0add5SPrasad Kanneganti 
204064fecd3eSFelix Manlunas 	if (resp->status) {
204150c0add5SPrasad Kanneganti 		dev_err(&oct_dev->pci_dev->dev,
204250c0add5SPrasad Kanneganti 			"Get interrupt moderation parameters failed\n");
204364fecd3eSFelix Manlunas 		WRITE_ONCE(sc->caller_is_done, true);
204464fecd3eSFelix Manlunas 		return -ENODEV;
204550c0add5SPrasad Kanneganti 	}
204650c0add5SPrasad Kanneganti 
204750c0add5SPrasad Kanneganti 	octeon_swap_8B_data((u64 *)&resp->intrmod,
204850c0add5SPrasad Kanneganti 			    (sizeof(struct oct_intrmod_cfg)) / 8);
204950c0add5SPrasad Kanneganti 	memcpy(intr_cfg, &resp->intrmod, sizeof(struct oct_intrmod_cfg));
205064fecd3eSFelix Manlunas 	WRITE_ONCE(sc->caller_is_done, true);
205150c0add5SPrasad Kanneganti 
205250c0add5SPrasad Kanneganti 	return 0;
2053f21fb3edSRaghu Vatsavayi }
2054f21fb3edSRaghu Vatsavayi 
2055f21fb3edSRaghu Vatsavayi /*  Configure interrupt moderation parameters */
octnet_set_intrmod_cfg(struct lio * lio,struct oct_intrmod_cfg * intr_cfg)205678e6a9b4SRaghu Vatsavayi static int octnet_set_intrmod_cfg(struct lio *lio,
205778e6a9b4SRaghu Vatsavayi 				  struct oct_intrmod_cfg *intr_cfg)
2058f21fb3edSRaghu Vatsavayi {
2059f21fb3edSRaghu Vatsavayi 	struct octeon_soft_command *sc;
2060f21fb3edSRaghu Vatsavayi 	struct oct_intrmod_cfg *cfg;
2061f21fb3edSRaghu Vatsavayi 	int retval;
206278e6a9b4SRaghu Vatsavayi 	struct octeon_device *oct_dev = lio->oct_dev;
2063f21fb3edSRaghu Vatsavayi 
2064f21fb3edSRaghu Vatsavayi 	/* Alloc soft command */
2065f21fb3edSRaghu Vatsavayi 	sc = (struct octeon_soft_command *)
2066f21fb3edSRaghu Vatsavayi 		octeon_alloc_soft_command(oct_dev,
2067f21fb3edSRaghu Vatsavayi 					  sizeof(struct oct_intrmod_cfg),
206864fecd3eSFelix Manlunas 					  16, 0);
2069f21fb3edSRaghu Vatsavayi 
2070f21fb3edSRaghu Vatsavayi 	if (!sc)
2071f21fb3edSRaghu Vatsavayi 		return -ENOMEM;
2072f21fb3edSRaghu Vatsavayi 
2073f21fb3edSRaghu Vatsavayi 	cfg = (struct oct_intrmod_cfg *)sc->virtdptr;
2074f21fb3edSRaghu Vatsavayi 
2075f21fb3edSRaghu Vatsavayi 	memcpy(cfg, intr_cfg, sizeof(struct oct_intrmod_cfg));
2076f21fb3edSRaghu Vatsavayi 	octeon_swap_8B_data((u64 *)cfg, (sizeof(struct oct_intrmod_cfg)) / 8);
2077f21fb3edSRaghu Vatsavayi 
207878e6a9b4SRaghu Vatsavayi 	sc->iq_no = lio->linfo.txpciq[0].s.q_no;
207978e6a9b4SRaghu Vatsavayi 
2080f21fb3edSRaghu Vatsavayi 	octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC,
2081f21fb3edSRaghu Vatsavayi 				    OPCODE_NIC_INTRMOD_CFG, 0, 0, 0);
2082f21fb3edSRaghu Vatsavayi 
208364fecd3eSFelix Manlunas 	init_completion(&sc->complete);
208464fecd3eSFelix Manlunas 	sc->sc_status = OCTEON_REQUEST_PENDING;
2085f21fb3edSRaghu Vatsavayi 
2086f21fb3edSRaghu Vatsavayi 	retval = octeon_send_soft_command(oct_dev, sc);
2087ddc173a6SRaghu Vatsavayi 	if (retval == IQ_SEND_FAILED) {
2088f21fb3edSRaghu Vatsavayi 		octeon_free_soft_command(oct_dev, sc);
2089f21fb3edSRaghu Vatsavayi 		return -EINVAL;
2090f21fb3edSRaghu Vatsavayi 	}
2091f21fb3edSRaghu Vatsavayi 
209250c0add5SPrasad Kanneganti 	/* Sleep on a wait queue till the cond flag indicates that the
209350c0add5SPrasad Kanneganti 	 * response arrived or timed-out.
209450c0add5SPrasad Kanneganti 	 */
209564fecd3eSFelix Manlunas 	retval = wait_for_sc_completion_timeout(oct_dev, sc, 0);
209650c0add5SPrasad Kanneganti 	if (retval)
209764fecd3eSFelix Manlunas 		return retval;
209864fecd3eSFelix Manlunas 
209964fecd3eSFelix Manlunas 	retval = sc->sc_status;
210064fecd3eSFelix Manlunas 	if (retval == 0) {
210150c0add5SPrasad Kanneganti 		dev_info(&oct_dev->pci_dev->dev,
210250c0add5SPrasad Kanneganti 			 "Rx-Adaptive Interrupt moderation %s\n",
210350c0add5SPrasad Kanneganti 			 (intr_cfg->rx_enable) ?
210450c0add5SPrasad Kanneganti 			 "enabled" : "disabled");
210564fecd3eSFelix Manlunas 		WRITE_ONCE(sc->caller_is_done, true);
210664fecd3eSFelix Manlunas 		return 0;
210750c0add5SPrasad Kanneganti 	}
210850c0add5SPrasad Kanneganti 
210964fecd3eSFelix Manlunas 	dev_err(&oct_dev->pci_dev->dev,
211064fecd3eSFelix Manlunas 		"intrmod config failed. Status: %x\n", retval);
211164fecd3eSFelix Manlunas 	WRITE_ONCE(sc->caller_is_done, true);
211264fecd3eSFelix Manlunas 	return -ENODEV;
2113f21fb3edSRaghu Vatsavayi }
2114f21fb3edSRaghu Vatsavayi 
lio_get_intr_coalesce(struct net_device * netdev,struct ethtool_coalesce * intr_coal,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)211550c0add5SPrasad Kanneganti static int lio_get_intr_coalesce(struct net_device *netdev,
2116f3ccfda1SYufeng Mo 				 struct ethtool_coalesce *intr_coal,
2117f3ccfda1SYufeng Mo 				 struct kernel_ethtool_coalesce *kernel_coal,
2118f3ccfda1SYufeng Mo 				 struct netlink_ext_ack *extack)
211950c0add5SPrasad Kanneganti {
212050c0add5SPrasad Kanneganti 	struct lio *lio = GET_LIO(netdev);
212150c0add5SPrasad Kanneganti 	struct octeon_device *oct = lio->oct_dev;
212250c0add5SPrasad Kanneganti 	struct octeon_instr_queue *iq;
212350c0add5SPrasad Kanneganti 	struct oct_intrmod_cfg intrmod_cfg;
212450c0add5SPrasad Kanneganti 
212550c0add5SPrasad Kanneganti 	if (octnet_get_intrmod_cfg(lio, &intrmod_cfg))
212650c0add5SPrasad Kanneganti 		return -ENODEV;
212750c0add5SPrasad Kanneganti 
212850c0add5SPrasad Kanneganti 	switch (oct->chip_id) {
212950c0add5SPrasad Kanneganti 	case OCTEON_CN23XX_PF_VID:
213050c0add5SPrasad Kanneganti 	case OCTEON_CN23XX_VF_VID: {
213150c0add5SPrasad Kanneganti 		if (!intrmod_cfg.rx_enable) {
213250c0add5SPrasad Kanneganti 			intr_coal->rx_coalesce_usecs = oct->rx_coalesce_usecs;
213350c0add5SPrasad Kanneganti 			intr_coal->rx_max_coalesced_frames =
213450c0add5SPrasad Kanneganti 				oct->rx_max_coalesced_frames;
213550c0add5SPrasad Kanneganti 		}
213650c0add5SPrasad Kanneganti 		if (!intrmod_cfg.tx_enable)
213750c0add5SPrasad Kanneganti 			intr_coal->tx_max_coalesced_frames =
213850c0add5SPrasad Kanneganti 				oct->tx_max_coalesced_frames;
213950c0add5SPrasad Kanneganti 		break;
214050c0add5SPrasad Kanneganti 	}
214150c0add5SPrasad Kanneganti 	case OCTEON_CN68XX:
214250c0add5SPrasad Kanneganti 	case OCTEON_CN66XX: {
214350c0add5SPrasad Kanneganti 		struct octeon_cn6xxx *cn6xxx =
214450c0add5SPrasad Kanneganti 			(struct octeon_cn6xxx *)oct->chip;
214550c0add5SPrasad Kanneganti 
214650c0add5SPrasad Kanneganti 		if (!intrmod_cfg.rx_enable) {
214750c0add5SPrasad Kanneganti 			intr_coal->rx_coalesce_usecs =
214850c0add5SPrasad Kanneganti 				CFG_GET_OQ_INTR_TIME(cn6xxx->conf);
214950c0add5SPrasad Kanneganti 			intr_coal->rx_max_coalesced_frames =
215050c0add5SPrasad Kanneganti 				CFG_GET_OQ_INTR_PKT(cn6xxx->conf);
215150c0add5SPrasad Kanneganti 		}
215250c0add5SPrasad Kanneganti 		iq = oct->instr_queue[lio->linfo.txpciq[0].s.q_no];
215350c0add5SPrasad Kanneganti 		intr_coal->tx_max_coalesced_frames = iq->fill_threshold;
215450c0add5SPrasad Kanneganti 		break;
215550c0add5SPrasad Kanneganti 	}
215650c0add5SPrasad Kanneganti 	default:
215750c0add5SPrasad Kanneganti 		netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n");
215850c0add5SPrasad Kanneganti 		return -EINVAL;
215950c0add5SPrasad Kanneganti 	}
216050c0add5SPrasad Kanneganti 	if (intrmod_cfg.rx_enable) {
216150c0add5SPrasad Kanneganti 		intr_coal->use_adaptive_rx_coalesce =
216250c0add5SPrasad Kanneganti 			intrmod_cfg.rx_enable;
216350c0add5SPrasad Kanneganti 		intr_coal->rate_sample_interval =
216450c0add5SPrasad Kanneganti 			intrmod_cfg.check_intrvl;
216550c0add5SPrasad Kanneganti 		intr_coal->pkt_rate_high =
216650c0add5SPrasad Kanneganti 			intrmod_cfg.maxpkt_ratethr;
216750c0add5SPrasad Kanneganti 		intr_coal->pkt_rate_low =
216850c0add5SPrasad Kanneganti 			intrmod_cfg.minpkt_ratethr;
216950c0add5SPrasad Kanneganti 		intr_coal->rx_max_coalesced_frames_high =
217050c0add5SPrasad Kanneganti 			intrmod_cfg.rx_maxcnt_trigger;
217150c0add5SPrasad Kanneganti 		intr_coal->rx_coalesce_usecs_high =
217250c0add5SPrasad Kanneganti 			intrmod_cfg.rx_maxtmr_trigger;
217350c0add5SPrasad Kanneganti 		intr_coal->rx_coalesce_usecs_low =
217450c0add5SPrasad Kanneganti 			intrmod_cfg.rx_mintmr_trigger;
217550c0add5SPrasad Kanneganti 		intr_coal->rx_max_coalesced_frames_low =
217650c0add5SPrasad Kanneganti 			intrmod_cfg.rx_mincnt_trigger;
217750c0add5SPrasad Kanneganti 	}
217850c0add5SPrasad Kanneganti 	if ((OCTEON_CN23XX_PF(oct) || OCTEON_CN23XX_VF(oct)) &&
217950c0add5SPrasad Kanneganti 	    (intrmod_cfg.tx_enable)) {
218050c0add5SPrasad Kanneganti 		intr_coal->use_adaptive_tx_coalesce =
218150c0add5SPrasad Kanneganti 			intrmod_cfg.tx_enable;
218250c0add5SPrasad Kanneganti 		intr_coal->tx_max_coalesced_frames_high =
218350c0add5SPrasad Kanneganti 			intrmod_cfg.tx_maxcnt_trigger;
218450c0add5SPrasad Kanneganti 		intr_coal->tx_max_coalesced_frames_low =
218550c0add5SPrasad Kanneganti 			intrmod_cfg.tx_mincnt_trigger;
218650c0add5SPrasad Kanneganti 	}
218750c0add5SPrasad Kanneganti 	return 0;
218850c0add5SPrasad Kanneganti }
218950c0add5SPrasad Kanneganti 
2190f21fb3edSRaghu Vatsavayi /* Enable/Disable auto interrupt Moderation */
oct_cfg_adaptive_intr(struct lio * lio,struct oct_intrmod_cfg * intrmod_cfg,struct ethtool_coalesce * intr_coal)219150c0add5SPrasad Kanneganti static int oct_cfg_adaptive_intr(struct lio *lio,
219250c0add5SPrasad Kanneganti 				 struct oct_intrmod_cfg *intrmod_cfg,
219350c0add5SPrasad Kanneganti 				 struct ethtool_coalesce *intr_coal)
2194f21fb3edSRaghu Vatsavayi {
2195f21fb3edSRaghu Vatsavayi 	int ret = 0;
2196f21fb3edSRaghu Vatsavayi 
219750c0add5SPrasad Kanneganti 	if (intrmod_cfg->rx_enable || intrmod_cfg->tx_enable) {
219850c0add5SPrasad Kanneganti 		intrmod_cfg->check_intrvl = intr_coal->rate_sample_interval;
219950c0add5SPrasad Kanneganti 		intrmod_cfg->maxpkt_ratethr = intr_coal->pkt_rate_high;
220050c0add5SPrasad Kanneganti 		intrmod_cfg->minpkt_ratethr = intr_coal->pkt_rate_low;
220178e6a9b4SRaghu Vatsavayi 	}
220250c0add5SPrasad Kanneganti 	if (intrmod_cfg->rx_enable) {
220378e6a9b4SRaghu Vatsavayi 		intrmod_cfg->rx_maxcnt_trigger =
2204f21fb3edSRaghu Vatsavayi 			intr_coal->rx_max_coalesced_frames_high;
220578e6a9b4SRaghu Vatsavayi 		intrmod_cfg->rx_maxtmr_trigger =
2206f21fb3edSRaghu Vatsavayi 			intr_coal->rx_coalesce_usecs_high;
220778e6a9b4SRaghu Vatsavayi 		intrmod_cfg->rx_mintmr_trigger =
2208f21fb3edSRaghu Vatsavayi 			intr_coal->rx_coalesce_usecs_low;
220978e6a9b4SRaghu Vatsavayi 		intrmod_cfg->rx_mincnt_trigger =
2210f21fb3edSRaghu Vatsavayi 			intr_coal->rx_max_coalesced_frames_low;
221178e6a9b4SRaghu Vatsavayi 	}
221250c0add5SPrasad Kanneganti 	if (intrmod_cfg->tx_enable) {
221378e6a9b4SRaghu Vatsavayi 		intrmod_cfg->tx_maxcnt_trigger =
221478e6a9b4SRaghu Vatsavayi 			intr_coal->tx_max_coalesced_frames_high;
221578e6a9b4SRaghu Vatsavayi 		intrmod_cfg->tx_mincnt_trigger =
221678e6a9b4SRaghu Vatsavayi 			intr_coal->tx_max_coalesced_frames_low;
2217f21fb3edSRaghu Vatsavayi 	}
2218f21fb3edSRaghu Vatsavayi 
221978e6a9b4SRaghu Vatsavayi 	ret = octnet_set_intrmod_cfg(lio, intrmod_cfg);
2220f21fb3edSRaghu Vatsavayi 
2221f21fb3edSRaghu Vatsavayi 	return ret;
2222f21fb3edSRaghu Vatsavayi }
2223f21fb3edSRaghu Vatsavayi 
2224f21fb3edSRaghu Vatsavayi static int
oct_cfg_rx_intrcnt(struct lio * lio,struct oct_intrmod_cfg * intrmod,struct ethtool_coalesce * intr_coal)222550c0add5SPrasad Kanneganti oct_cfg_rx_intrcnt(struct lio *lio,
222650c0add5SPrasad Kanneganti 		   struct oct_intrmod_cfg *intrmod,
222750c0add5SPrasad Kanneganti 		   struct ethtool_coalesce *intr_coal)
2228f21fb3edSRaghu Vatsavayi {
2229f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
2230f21fb3edSRaghu Vatsavayi 	u32 rx_max_coalesced_frames;
2231f21fb3edSRaghu Vatsavayi 
223278e6a9b4SRaghu Vatsavayi 	/* Config Cnt based interrupt values */
223378e6a9b4SRaghu Vatsavayi 	switch (oct->chip_id) {
223478e6a9b4SRaghu Vatsavayi 	case OCTEON_CN68XX:
223578e6a9b4SRaghu Vatsavayi 	case OCTEON_CN66XX: {
223678e6a9b4SRaghu Vatsavayi 		struct octeon_cn6xxx *cn6xxx =
223778e6a9b4SRaghu Vatsavayi 			(struct octeon_cn6xxx *)oct->chip;
223878e6a9b4SRaghu Vatsavayi 
2239f21fb3edSRaghu Vatsavayi 		if (!intr_coal->rx_max_coalesced_frames)
2240f21fb3edSRaghu Vatsavayi 			rx_max_coalesced_frames = CN6XXX_OQ_INTR_PKT;
2241f21fb3edSRaghu Vatsavayi 		else
224278e6a9b4SRaghu Vatsavayi 			rx_max_coalesced_frames =
224378e6a9b4SRaghu Vatsavayi 				intr_coal->rx_max_coalesced_frames;
2244f21fb3edSRaghu Vatsavayi 		octeon_write_csr(oct, CN6XXX_SLI_OQ_INT_LEVEL_PKTS,
2245f21fb3edSRaghu Vatsavayi 				 rx_max_coalesced_frames);
2246f21fb3edSRaghu Vatsavayi 		CFG_SET_OQ_INTR_PKT(cn6xxx->conf, rx_max_coalesced_frames);
224778e6a9b4SRaghu Vatsavayi 		break;
224878e6a9b4SRaghu Vatsavayi 	}
2249dc3abcbeSRaghu Vatsavayi 	case OCTEON_CN23XX_PF_VID: {
2250dc3abcbeSRaghu Vatsavayi 		int q_no;
2251dc3abcbeSRaghu Vatsavayi 
2252dc3abcbeSRaghu Vatsavayi 		if (!intr_coal->rx_max_coalesced_frames)
225350c0add5SPrasad Kanneganti 			rx_max_coalesced_frames = intrmod->rx_frames;
2254dc3abcbeSRaghu Vatsavayi 		else
2255dc3abcbeSRaghu Vatsavayi 			rx_max_coalesced_frames =
2256dc3abcbeSRaghu Vatsavayi 			    intr_coal->rx_max_coalesced_frames;
2257dc3abcbeSRaghu Vatsavayi 		for (q_no = 0; q_no < oct->num_oqs; q_no++) {
2258dc3abcbeSRaghu Vatsavayi 			q_no += oct->sriov_info.pf_srn;
2259dc3abcbeSRaghu Vatsavayi 			octeon_write_csr64(
2260dc3abcbeSRaghu Vatsavayi 			    oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no),
2261dc3abcbeSRaghu Vatsavayi 			    (octeon_read_csr64(
2262dc3abcbeSRaghu Vatsavayi 				 oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no)) &
2263dc3abcbeSRaghu Vatsavayi 			     (0x3fffff00000000UL)) |
226450c0add5SPrasad Kanneganti 				(rx_max_coalesced_frames - 1));
2265dc3abcbeSRaghu Vatsavayi 			/*consider setting resend bit*/
2266dc3abcbeSRaghu Vatsavayi 		}
226750c0add5SPrasad Kanneganti 		intrmod->rx_frames = rx_max_coalesced_frames;
226850c0add5SPrasad Kanneganti 		oct->rx_max_coalesced_frames = rx_max_coalesced_frames;
2269dc3abcbeSRaghu Vatsavayi 		break;
2270dc3abcbeSRaghu Vatsavayi 	}
2271d8ab848cSRaghu Vatsavayi 	case OCTEON_CN23XX_VF_VID: {
2272d8ab848cSRaghu Vatsavayi 		int q_no;
2273d8ab848cSRaghu Vatsavayi 
2274d8ab848cSRaghu Vatsavayi 		if (!intr_coal->rx_max_coalesced_frames)
227550c0add5SPrasad Kanneganti 			rx_max_coalesced_frames = intrmod->rx_frames;
2276d8ab848cSRaghu Vatsavayi 		else
2277d8ab848cSRaghu Vatsavayi 			rx_max_coalesced_frames =
2278d8ab848cSRaghu Vatsavayi 			    intr_coal->rx_max_coalesced_frames;
2279d8ab848cSRaghu Vatsavayi 		for (q_no = 0; q_no < oct->num_oqs; q_no++) {
2280d8ab848cSRaghu Vatsavayi 			octeon_write_csr64(
2281d8ab848cSRaghu Vatsavayi 			    oct, CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(q_no),
2282d8ab848cSRaghu Vatsavayi 			    (octeon_read_csr64(
2283d8ab848cSRaghu Vatsavayi 				 oct, CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(q_no)) &
2284d8ab848cSRaghu Vatsavayi 			     (0x3fffff00000000UL)) |
22850430a260SWeilin Chang 				(rx_max_coalesced_frames - 1));
2286d8ab848cSRaghu Vatsavayi 			/*consider writing to resend bit here*/
2287d8ab848cSRaghu Vatsavayi 		}
228850c0add5SPrasad Kanneganti 		intrmod->rx_frames = rx_max_coalesced_frames;
228950c0add5SPrasad Kanneganti 		oct->rx_max_coalesced_frames = rx_max_coalesced_frames;
2290d8ab848cSRaghu Vatsavayi 		break;
2291d8ab848cSRaghu Vatsavayi 	}
229278e6a9b4SRaghu Vatsavayi 	default:
229378e6a9b4SRaghu Vatsavayi 		return -EINVAL;
229478e6a9b4SRaghu Vatsavayi 	}
2295f21fb3edSRaghu Vatsavayi 	return 0;
2296f21fb3edSRaghu Vatsavayi }
2297f21fb3edSRaghu Vatsavayi 
oct_cfg_rx_intrtime(struct lio * lio,struct oct_intrmod_cfg * intrmod,struct ethtool_coalesce * intr_coal)229832581245SRaghu Vatsavayi static int oct_cfg_rx_intrtime(struct lio *lio,
229950c0add5SPrasad Kanneganti 			       struct oct_intrmod_cfg *intrmod,
230032581245SRaghu Vatsavayi 			       struct ethtool_coalesce *intr_coal)
2301f21fb3edSRaghu Vatsavayi {
2302f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
2303f21fb3edSRaghu Vatsavayi 	u32 time_threshold, rx_coalesce_usecs;
2304f21fb3edSRaghu Vatsavayi 
230578e6a9b4SRaghu Vatsavayi 	/* Config Time based interrupt values */
230678e6a9b4SRaghu Vatsavayi 	switch (oct->chip_id) {
230778e6a9b4SRaghu Vatsavayi 	case OCTEON_CN68XX:
230878e6a9b4SRaghu Vatsavayi 	case OCTEON_CN66XX: {
230978e6a9b4SRaghu Vatsavayi 		struct octeon_cn6xxx *cn6xxx =
231078e6a9b4SRaghu Vatsavayi 			(struct octeon_cn6xxx *)oct->chip;
2311f21fb3edSRaghu Vatsavayi 		if (!intr_coal->rx_coalesce_usecs)
2312f21fb3edSRaghu Vatsavayi 			rx_coalesce_usecs = CN6XXX_OQ_INTR_TIME;
2313f21fb3edSRaghu Vatsavayi 		else
2314f21fb3edSRaghu Vatsavayi 			rx_coalesce_usecs = intr_coal->rx_coalesce_usecs;
2315f21fb3edSRaghu Vatsavayi 
231678e6a9b4SRaghu Vatsavayi 		time_threshold = lio_cn6xxx_get_oq_ticks(oct,
231778e6a9b4SRaghu Vatsavayi 							 rx_coalesce_usecs);
231878e6a9b4SRaghu Vatsavayi 		octeon_write_csr(oct,
231978e6a9b4SRaghu Vatsavayi 				 CN6XXX_SLI_OQ_INT_LEVEL_TIME,
232078e6a9b4SRaghu Vatsavayi 				 time_threshold);
2321f21fb3edSRaghu Vatsavayi 
2322f21fb3edSRaghu Vatsavayi 		CFG_SET_OQ_INTR_TIME(cn6xxx->conf, rx_coalesce_usecs);
232378e6a9b4SRaghu Vatsavayi 		break;
232478e6a9b4SRaghu Vatsavayi 	}
2325dc3abcbeSRaghu Vatsavayi 	case OCTEON_CN23XX_PF_VID: {
2326dc3abcbeSRaghu Vatsavayi 		u64 time_threshold;
2327dc3abcbeSRaghu Vatsavayi 		int q_no;
2328dc3abcbeSRaghu Vatsavayi 
2329dc3abcbeSRaghu Vatsavayi 		if (!intr_coal->rx_coalesce_usecs)
233050c0add5SPrasad Kanneganti 			rx_coalesce_usecs = intrmod->rx_usecs;
2331dc3abcbeSRaghu Vatsavayi 		else
2332dc3abcbeSRaghu Vatsavayi 			rx_coalesce_usecs = intr_coal->rx_coalesce_usecs;
2333dc3abcbeSRaghu Vatsavayi 		time_threshold =
2334dc3abcbeSRaghu Vatsavayi 		    cn23xx_pf_get_oq_ticks(oct, (u32)rx_coalesce_usecs);
2335dc3abcbeSRaghu Vatsavayi 		for (q_no = 0; q_no < oct->num_oqs; q_no++) {
2336dc3abcbeSRaghu Vatsavayi 			q_no += oct->sriov_info.pf_srn;
2337dc3abcbeSRaghu Vatsavayi 			octeon_write_csr64(oct,
2338dc3abcbeSRaghu Vatsavayi 					   CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no),
233950c0add5SPrasad Kanneganti 					   (intrmod->rx_frames |
234050c0add5SPrasad Kanneganti 					    ((u64)time_threshold << 32)));
2341dc3abcbeSRaghu Vatsavayi 			/*consider writing to resend bit here*/
2342dc3abcbeSRaghu Vatsavayi 		}
234350c0add5SPrasad Kanneganti 		intrmod->rx_usecs = rx_coalesce_usecs;
234450c0add5SPrasad Kanneganti 		oct->rx_coalesce_usecs = rx_coalesce_usecs;
2345dc3abcbeSRaghu Vatsavayi 		break;
2346dc3abcbeSRaghu Vatsavayi 	}
2347d8ab848cSRaghu Vatsavayi 	case OCTEON_CN23XX_VF_VID: {
2348d8ab848cSRaghu Vatsavayi 		u64 time_threshold;
2349d8ab848cSRaghu Vatsavayi 		int q_no;
2350d8ab848cSRaghu Vatsavayi 
2351d8ab848cSRaghu Vatsavayi 		if (!intr_coal->rx_coalesce_usecs)
235250c0add5SPrasad Kanneganti 			rx_coalesce_usecs = intrmod->rx_usecs;
2353d8ab848cSRaghu Vatsavayi 		else
2354d8ab848cSRaghu Vatsavayi 			rx_coalesce_usecs = intr_coal->rx_coalesce_usecs;
2355d8ab848cSRaghu Vatsavayi 
2356d8ab848cSRaghu Vatsavayi 		time_threshold =
2357d8ab848cSRaghu Vatsavayi 		    cn23xx_vf_get_oq_ticks(oct, (u32)rx_coalesce_usecs);
2358d8ab848cSRaghu Vatsavayi 		for (q_no = 0; q_no < oct->num_oqs; q_no++) {
2359d8ab848cSRaghu Vatsavayi 			octeon_write_csr64(
2360d8ab848cSRaghu Vatsavayi 				oct, CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(q_no),
236150c0add5SPrasad Kanneganti 				(intrmod->rx_frames |
236250c0add5SPrasad Kanneganti 				 ((u64)time_threshold << 32)));
2363d8ab848cSRaghu Vatsavayi 			/*consider setting resend bit*/
2364d8ab848cSRaghu Vatsavayi 		}
236550c0add5SPrasad Kanneganti 		intrmod->rx_usecs = rx_coalesce_usecs;
236650c0add5SPrasad Kanneganti 		oct->rx_coalesce_usecs = rx_coalesce_usecs;
2367d8ab848cSRaghu Vatsavayi 		break;
2368d8ab848cSRaghu Vatsavayi 	}
236978e6a9b4SRaghu Vatsavayi 	default:
237078e6a9b4SRaghu Vatsavayi 		return -EINVAL;
237178e6a9b4SRaghu Vatsavayi 	}
2372f21fb3edSRaghu Vatsavayi 
2373f21fb3edSRaghu Vatsavayi 	return 0;
2374f21fb3edSRaghu Vatsavayi }
2375f21fb3edSRaghu Vatsavayi 
237678e6a9b4SRaghu Vatsavayi static int
oct_cfg_tx_intrcnt(struct lio * lio,struct oct_intrmod_cfg * intrmod,struct ethtool_coalesce * intr_coal)237750c0add5SPrasad Kanneganti oct_cfg_tx_intrcnt(struct lio *lio,
237850c0add5SPrasad Kanneganti 		   struct oct_intrmod_cfg *intrmod,
237950c0add5SPrasad Kanneganti 		   struct ethtool_coalesce *intr_coal)
238078e6a9b4SRaghu Vatsavayi {
238178e6a9b4SRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
2382dc3abcbeSRaghu Vatsavayi 	u32 iq_intr_pkt;
2383dc3abcbeSRaghu Vatsavayi 	void __iomem *inst_cnt_reg;
2384dc3abcbeSRaghu Vatsavayi 	u64 val;
238578e6a9b4SRaghu Vatsavayi 
238678e6a9b4SRaghu Vatsavayi 	/* Config Cnt based interrupt values */
238778e6a9b4SRaghu Vatsavayi 	switch (oct->chip_id) {
238878e6a9b4SRaghu Vatsavayi 	case OCTEON_CN68XX:
238978e6a9b4SRaghu Vatsavayi 	case OCTEON_CN66XX:
239078e6a9b4SRaghu Vatsavayi 		break;
2391d8ab848cSRaghu Vatsavayi 	case OCTEON_CN23XX_VF_VID:
2392dc3abcbeSRaghu Vatsavayi 	case OCTEON_CN23XX_PF_VID: {
2393dc3abcbeSRaghu Vatsavayi 		int q_no;
2394dc3abcbeSRaghu Vatsavayi 
2395dc3abcbeSRaghu Vatsavayi 		if (!intr_coal->tx_max_coalesced_frames)
2396dc3abcbeSRaghu Vatsavayi 			iq_intr_pkt = CN23XX_DEF_IQ_INTR_THRESHOLD &
2397dc3abcbeSRaghu Vatsavayi 				      CN23XX_PKT_IN_DONE_WMARK_MASK;
2398dc3abcbeSRaghu Vatsavayi 		else
2399dc3abcbeSRaghu Vatsavayi 			iq_intr_pkt = intr_coal->tx_max_coalesced_frames &
2400dc3abcbeSRaghu Vatsavayi 				      CN23XX_PKT_IN_DONE_WMARK_MASK;
2401dc3abcbeSRaghu Vatsavayi 		for (q_no = 0; q_no < oct->num_iqs; q_no++) {
2402dc3abcbeSRaghu Vatsavayi 			inst_cnt_reg = (oct->instr_queue[q_no])->inst_cnt_reg;
2403dc3abcbeSRaghu Vatsavayi 			val = readq(inst_cnt_reg);
2404dc3abcbeSRaghu Vatsavayi 			/*clear wmark and count.dont want to write count back*/
2405dc3abcbeSRaghu Vatsavayi 			val = (val & 0xFFFF000000000000ULL) |
240650c0add5SPrasad Kanneganti 			      ((u64)(iq_intr_pkt - 1)
2407dc3abcbeSRaghu Vatsavayi 			       << CN23XX_PKT_IN_DONE_WMARK_BIT_POS);
2408dc3abcbeSRaghu Vatsavayi 			writeq(val, inst_cnt_reg);
2409dc3abcbeSRaghu Vatsavayi 			/*consider setting resend bit*/
2410dc3abcbeSRaghu Vatsavayi 		}
241150c0add5SPrasad Kanneganti 		intrmod->tx_frames = iq_intr_pkt;
241250c0add5SPrasad Kanneganti 		oct->tx_max_coalesced_frames = iq_intr_pkt;
2413dc3abcbeSRaghu Vatsavayi 		break;
2414dc3abcbeSRaghu Vatsavayi 	}
241578e6a9b4SRaghu Vatsavayi 	default:
241678e6a9b4SRaghu Vatsavayi 		return -EINVAL;
241778e6a9b4SRaghu Vatsavayi 	}
241878e6a9b4SRaghu Vatsavayi 	return 0;
241978e6a9b4SRaghu Vatsavayi }
242078e6a9b4SRaghu Vatsavayi 
lio_set_intr_coalesce(struct net_device * netdev,struct ethtool_coalesce * intr_coal,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)2421f21fb3edSRaghu Vatsavayi static int lio_set_intr_coalesce(struct net_device *netdev,
2422f3ccfda1SYufeng Mo 				 struct ethtool_coalesce *intr_coal,
2423f3ccfda1SYufeng Mo 				 struct kernel_ethtool_coalesce *kernel_coal,
2424f3ccfda1SYufeng Mo 				 struct netlink_ext_ack *extack)
2425f21fb3edSRaghu Vatsavayi {
2426f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
2427f21fb3edSRaghu Vatsavayi 	int ret;
2428f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
242950c0add5SPrasad Kanneganti 	struct oct_intrmod_cfg intrmod = {0};
2430f21fb3edSRaghu Vatsavayi 	u32 j, q_no;
243178e6a9b4SRaghu Vatsavayi 	int db_max, db_min;
2432f21fb3edSRaghu Vatsavayi 
243378e6a9b4SRaghu Vatsavayi 	switch (oct->chip_id) {
243478e6a9b4SRaghu Vatsavayi 	case OCTEON_CN68XX:
243578e6a9b4SRaghu Vatsavayi 	case OCTEON_CN66XX:
243678e6a9b4SRaghu Vatsavayi 		db_min = CN6XXX_DB_MIN;
243778e6a9b4SRaghu Vatsavayi 		db_max = CN6XXX_DB_MAX;
243878e6a9b4SRaghu Vatsavayi 		if ((intr_coal->tx_max_coalesced_frames >= db_min) &&
243978e6a9b4SRaghu Vatsavayi 		    (intr_coal->tx_max_coalesced_frames <= db_max)) {
2440f21fb3edSRaghu Vatsavayi 			for (j = 0; j < lio->linfo.num_txpciq; j++) {
244126236fa9SRaghu Vatsavayi 				q_no = lio->linfo.txpciq[j].s.q_no;
2442f21fb3edSRaghu Vatsavayi 				oct->instr_queue[q_no]->fill_threshold =
2443f21fb3edSRaghu Vatsavayi 					intr_coal->tx_max_coalesced_frames;
2444f21fb3edSRaghu Vatsavayi 			}
2445f21fb3edSRaghu Vatsavayi 		} else {
2446f21fb3edSRaghu Vatsavayi 			dev_err(&oct->pci_dev->dev,
2447f21fb3edSRaghu Vatsavayi 				"LIQUIDIO: Invalid tx-frames:%d. Range is min:%d max:%d\n",
244850c0add5SPrasad Kanneganti 				intr_coal->tx_max_coalesced_frames,
244950c0add5SPrasad Kanneganti 				db_min, db_max);
245078e6a9b4SRaghu Vatsavayi 			return -EINVAL;
245178e6a9b4SRaghu Vatsavayi 		}
245278e6a9b4SRaghu Vatsavayi 		break;
2453dc3abcbeSRaghu Vatsavayi 	case OCTEON_CN23XX_PF_VID:
2454d8ab848cSRaghu Vatsavayi 	case OCTEON_CN23XX_VF_VID:
2455dc3abcbeSRaghu Vatsavayi 		break;
245678e6a9b4SRaghu Vatsavayi 	default:
2457f21fb3edSRaghu Vatsavayi 		return -EINVAL;
2458f21fb3edSRaghu Vatsavayi 	}
2459f21fb3edSRaghu Vatsavayi 
246050c0add5SPrasad Kanneganti 	intrmod.rx_enable = intr_coal->use_adaptive_rx_coalesce ? 1 : 0;
246150c0add5SPrasad Kanneganti 	intrmod.tx_enable = intr_coal->use_adaptive_tx_coalesce ? 1 : 0;
246250c0add5SPrasad Kanneganti 	intrmod.rx_frames = CFG_GET_OQ_INTR_PKT(octeon_get_conf(oct));
246350c0add5SPrasad Kanneganti 	intrmod.rx_usecs = CFG_GET_OQ_INTR_TIME(octeon_get_conf(oct));
246450c0add5SPrasad Kanneganti 	intrmod.tx_frames = CFG_GET_IQ_INTR_PKT(octeon_get_conf(oct));
2465f21fb3edSRaghu Vatsavayi 
246650c0add5SPrasad Kanneganti 	ret = oct_cfg_adaptive_intr(lio, &intrmod, intr_coal);
2467f21fb3edSRaghu Vatsavayi 
246878e6a9b4SRaghu Vatsavayi 	if (!intr_coal->use_adaptive_rx_coalesce) {
246950c0add5SPrasad Kanneganti 		ret = oct_cfg_rx_intrtime(lio, &intrmod, intr_coal);
2470f21fb3edSRaghu Vatsavayi 		if (ret)
2471f21fb3edSRaghu Vatsavayi 			goto ret_intrmod;
2472f21fb3edSRaghu Vatsavayi 
247350c0add5SPrasad Kanneganti 		ret = oct_cfg_rx_intrcnt(lio, &intrmod, intr_coal);
2474f21fb3edSRaghu Vatsavayi 		if (ret)
2475f21fb3edSRaghu Vatsavayi 			goto ret_intrmod;
247650c0add5SPrasad Kanneganti 	} else {
247750c0add5SPrasad Kanneganti 		oct->rx_coalesce_usecs =
247850c0add5SPrasad Kanneganti 			CFG_GET_OQ_INTR_TIME(octeon_get_conf(oct));
247950c0add5SPrasad Kanneganti 		oct->rx_max_coalesced_frames =
248050c0add5SPrasad Kanneganti 			CFG_GET_OQ_INTR_PKT(octeon_get_conf(oct));
2481f21fb3edSRaghu Vatsavayi 	}
248250c0add5SPrasad Kanneganti 
248378e6a9b4SRaghu Vatsavayi 	if (!intr_coal->use_adaptive_tx_coalesce) {
248450c0add5SPrasad Kanneganti 		ret = oct_cfg_tx_intrcnt(lio, &intrmod, intr_coal);
248578e6a9b4SRaghu Vatsavayi 		if (ret)
248678e6a9b4SRaghu Vatsavayi 			goto ret_intrmod;
248750c0add5SPrasad Kanneganti 	} else {
248850c0add5SPrasad Kanneganti 		oct->tx_max_coalesced_frames =
248950c0add5SPrasad Kanneganti 			CFG_GET_IQ_INTR_PKT(octeon_get_conf(oct));
249078e6a9b4SRaghu Vatsavayi 	}
2491f21fb3edSRaghu Vatsavayi 
2492f21fb3edSRaghu Vatsavayi 	return 0;
2493f21fb3edSRaghu Vatsavayi ret_intrmod:
2494f21fb3edSRaghu Vatsavayi 	return ret;
2495f21fb3edSRaghu Vatsavayi }
2496f21fb3edSRaghu Vatsavayi 
lio_get_ts_info(struct net_device * netdev,struct ethtool_ts_info * info)2497f21fb3edSRaghu Vatsavayi static int lio_get_ts_info(struct net_device *netdev,
2498f21fb3edSRaghu Vatsavayi 			   struct ethtool_ts_info *info)
2499f21fb3edSRaghu Vatsavayi {
2500f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
2501f21fb3edSRaghu Vatsavayi 
2502f21fb3edSRaghu Vatsavayi 	info->so_timestamping =
2503178cc10eSRaghu Vatsavayi #ifdef PTP_HARDWARE_TIMESTAMPING
2504f21fb3edSRaghu Vatsavayi 		SOF_TIMESTAMPING_TX_HARDWARE |
2505f21fb3edSRaghu Vatsavayi 		SOF_TIMESTAMPING_RX_HARDWARE |
2506178cc10eSRaghu Vatsavayi 		SOF_TIMESTAMPING_RAW_HARDWARE |
2507178cc10eSRaghu Vatsavayi 		SOF_TIMESTAMPING_TX_SOFTWARE |
2508178cc10eSRaghu Vatsavayi #endif
2509f21fb3edSRaghu Vatsavayi 		SOF_TIMESTAMPING_RX_SOFTWARE |
2510178cc10eSRaghu Vatsavayi 		SOF_TIMESTAMPING_SOFTWARE;
2511f21fb3edSRaghu Vatsavayi 
2512f21fb3edSRaghu Vatsavayi 	if (lio->ptp_clock)
2513f21fb3edSRaghu Vatsavayi 		info->phc_index = ptp_clock_index(lio->ptp_clock);
2514f21fb3edSRaghu Vatsavayi 	else
2515f21fb3edSRaghu Vatsavayi 		info->phc_index = -1;
2516f21fb3edSRaghu Vatsavayi 
2517178cc10eSRaghu Vatsavayi #ifdef PTP_HARDWARE_TIMESTAMPING
2518f21fb3edSRaghu Vatsavayi 	info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
2519f21fb3edSRaghu Vatsavayi 
2520f21fb3edSRaghu Vatsavayi 	info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
2521f21fb3edSRaghu Vatsavayi 			   (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
2522f21fb3edSRaghu Vatsavayi 			   (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
2523f21fb3edSRaghu Vatsavayi 			   (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
2524178cc10eSRaghu Vatsavayi #endif
2525f21fb3edSRaghu Vatsavayi 
2526f21fb3edSRaghu Vatsavayi 	return 0;
2527f21fb3edSRaghu Vatsavayi }
2528f21fb3edSRaghu Vatsavayi 
2529f21fb3edSRaghu Vatsavayi /* Return register dump len. */
lio_get_regs_len(struct net_device * dev)2530dc3abcbeSRaghu Vatsavayi static int lio_get_regs_len(struct net_device *dev)
2531f21fb3edSRaghu Vatsavayi {
2532dc3abcbeSRaghu Vatsavayi 	struct lio *lio = GET_LIO(dev);
2533dc3abcbeSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
2534dc3abcbeSRaghu Vatsavayi 
2535dc3abcbeSRaghu Vatsavayi 	switch (oct->chip_id) {
2536dc3abcbeSRaghu Vatsavayi 	case OCTEON_CN23XX_PF_VID:
2537dc3abcbeSRaghu Vatsavayi 		return OCT_ETHTOOL_REGDUMP_LEN_23XX;
2538d8ab848cSRaghu Vatsavayi 	case OCTEON_CN23XX_VF_VID:
2539d8ab848cSRaghu Vatsavayi 		return OCT_ETHTOOL_REGDUMP_LEN_23XX_VF;
2540dc3abcbeSRaghu Vatsavayi 	default:
2541f21fb3edSRaghu Vatsavayi 		return OCT_ETHTOOL_REGDUMP_LEN;
2542f21fb3edSRaghu Vatsavayi 	}
2543dc3abcbeSRaghu Vatsavayi }
2544dc3abcbeSRaghu Vatsavayi 
cn23xx_read_csr_reg(char * s,struct octeon_device * oct)2545dc3abcbeSRaghu Vatsavayi static int cn23xx_read_csr_reg(char *s, struct octeon_device *oct)
2546dc3abcbeSRaghu Vatsavayi {
2547dc3abcbeSRaghu Vatsavayi 	u32 reg;
2548dc3abcbeSRaghu Vatsavayi 	u8 pf_num = oct->pf_num;
2549dc3abcbeSRaghu Vatsavayi 	int len = 0;
2550dc3abcbeSRaghu Vatsavayi 	int i;
2551dc3abcbeSRaghu Vatsavayi 
2552dc3abcbeSRaghu Vatsavayi 	/* PCI  Window Registers */
2553dc3abcbeSRaghu Vatsavayi 
2554dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n");
2555dc3abcbeSRaghu Vatsavayi 
2556dc3abcbeSRaghu Vatsavayi 	/*0x29030 or 0x29040*/
2557dc3abcbeSRaghu Vatsavayi 	reg = CN23XX_SLI_PKT_MAC_RINFO64(oct->pcie_port, oct->pf_num);
2558dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len,
2559dc3abcbeSRaghu Vatsavayi 		       "\n[%08x] (SLI_PKT_MAC%d_PF%d_RINFO): %016llx\n",
2560dc3abcbeSRaghu Vatsavayi 		       reg, oct->pcie_port, oct->pf_num,
2561dc3abcbeSRaghu Vatsavayi 		       (u64)octeon_read_csr64(oct, reg));
2562dc3abcbeSRaghu Vatsavayi 
2563dc3abcbeSRaghu Vatsavayi 	/*0x27080 or 0x27090*/
2564dc3abcbeSRaghu Vatsavayi 	reg = CN23XX_SLI_MAC_PF_INT_ENB64(oct->pcie_port, oct->pf_num);
2565dc3abcbeSRaghu Vatsavayi 	len +=
2566dc3abcbeSRaghu Vatsavayi 	    sprintf(s + len, "\n[%08x] (SLI_MAC%d_PF%d_INT_ENB): %016llx\n",
2567dc3abcbeSRaghu Vatsavayi 		    reg, oct->pcie_port, oct->pf_num,
2568dc3abcbeSRaghu Vatsavayi 		    (u64)octeon_read_csr64(oct, reg));
2569dc3abcbeSRaghu Vatsavayi 
2570dc3abcbeSRaghu Vatsavayi 	/*0x27000 or 0x27010*/
2571dc3abcbeSRaghu Vatsavayi 	reg = CN23XX_SLI_MAC_PF_INT_SUM64(oct->pcie_port, oct->pf_num);
2572dc3abcbeSRaghu Vatsavayi 	len +=
2573dc3abcbeSRaghu Vatsavayi 	    sprintf(s + len, "\n[%08x] (SLI_MAC%d_PF%d_INT_SUM): %016llx\n",
2574dc3abcbeSRaghu Vatsavayi 		    reg, oct->pcie_port, oct->pf_num,
2575dc3abcbeSRaghu Vatsavayi 		    (u64)octeon_read_csr64(oct, reg));
2576dc3abcbeSRaghu Vatsavayi 
2577dc3abcbeSRaghu Vatsavayi 	/*0x29120*/
2578dc3abcbeSRaghu Vatsavayi 	reg = 0x29120;
2579dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%08x] (SLI_PKT_MEM_CTL): %016llx\n", reg,
2580dc3abcbeSRaghu Vatsavayi 		       (u64)octeon_read_csr64(oct, reg));
2581dc3abcbeSRaghu Vatsavayi 
2582dc3abcbeSRaghu Vatsavayi 	/*0x27300*/
2583dc3abcbeSRaghu Vatsavayi 	reg = 0x27300 + oct->pcie_port * CN23XX_MAC_INT_OFFSET +
2584dc3abcbeSRaghu Vatsavayi 	      (oct->pf_num) * CN23XX_PF_INT_OFFSET;
2585dc3abcbeSRaghu Vatsavayi 	len += sprintf(
2586dc3abcbeSRaghu Vatsavayi 	    s + len, "\n[%08x] (SLI_MAC%d_PF%d_PKT_VF_INT): %016llx\n", reg,
2587dc3abcbeSRaghu Vatsavayi 	    oct->pcie_port, oct->pf_num, (u64)octeon_read_csr64(oct, reg));
2588dc3abcbeSRaghu Vatsavayi 
2589dc3abcbeSRaghu Vatsavayi 	/*0x27200*/
2590dc3abcbeSRaghu Vatsavayi 	reg = 0x27200 + oct->pcie_port * CN23XX_MAC_INT_OFFSET +
2591dc3abcbeSRaghu Vatsavayi 	      (oct->pf_num) * CN23XX_PF_INT_OFFSET;
2592dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len,
2593dc3abcbeSRaghu Vatsavayi 		       "\n[%08x] (SLI_MAC%d_PF%d_PP_VF_INT): %016llx\n",
2594dc3abcbeSRaghu Vatsavayi 		       reg, oct->pcie_port, oct->pf_num,
2595dc3abcbeSRaghu Vatsavayi 		       (u64)octeon_read_csr64(oct, reg));
2596dc3abcbeSRaghu Vatsavayi 
2597dc3abcbeSRaghu Vatsavayi 	/*29130*/
2598dc3abcbeSRaghu Vatsavayi 	reg = CN23XX_SLI_PKT_CNT_INT;
2599dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%08x] (SLI_PKT_CNT_INT): %016llx\n", reg,
2600dc3abcbeSRaghu Vatsavayi 		       (u64)octeon_read_csr64(oct, reg));
2601dc3abcbeSRaghu Vatsavayi 
2602dc3abcbeSRaghu Vatsavayi 	/*0x29140*/
2603dc3abcbeSRaghu Vatsavayi 	reg = CN23XX_SLI_PKT_TIME_INT;
2604dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%08x] (SLI_PKT_TIME_INT): %016llx\n", reg,
2605dc3abcbeSRaghu Vatsavayi 		       (u64)octeon_read_csr64(oct, reg));
2606dc3abcbeSRaghu Vatsavayi 
2607dc3abcbeSRaghu Vatsavayi 	/*0x29160*/
2608dc3abcbeSRaghu Vatsavayi 	reg = 0x29160;
2609dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%08x] (SLI_PKT_INT): %016llx\n", reg,
2610dc3abcbeSRaghu Vatsavayi 		       (u64)octeon_read_csr64(oct, reg));
2611dc3abcbeSRaghu Vatsavayi 
2612dc3abcbeSRaghu Vatsavayi 	/*0x29180*/
2613dc3abcbeSRaghu Vatsavayi 	reg = CN23XX_SLI_OQ_WMARK;
2614dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%08x] (SLI_PKT_OUTPUT_WMARK): %016llx\n",
2615dc3abcbeSRaghu Vatsavayi 		       reg, (u64)octeon_read_csr64(oct, reg));
2616dc3abcbeSRaghu Vatsavayi 
2617dc3abcbeSRaghu Vatsavayi 	/*0x291E0*/
2618dc3abcbeSRaghu Vatsavayi 	reg = CN23XX_SLI_PKT_IOQ_RING_RST;
2619dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%08x] (SLI_PKT_RING_RST): %016llx\n", reg,
2620dc3abcbeSRaghu Vatsavayi 		       (u64)octeon_read_csr64(oct, reg));
2621dc3abcbeSRaghu Vatsavayi 
2622dc3abcbeSRaghu Vatsavayi 	/*0x29210*/
2623dc3abcbeSRaghu Vatsavayi 	reg = CN23XX_SLI_GBL_CONTROL;
2624dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len,
2625dc3abcbeSRaghu Vatsavayi 		       "\n[%08x] (SLI_PKT_GBL_CONTROL): %016llx\n", reg,
2626dc3abcbeSRaghu Vatsavayi 		       (u64)octeon_read_csr64(oct, reg));
2627dc3abcbeSRaghu Vatsavayi 
2628dc3abcbeSRaghu Vatsavayi 	/*0x29220*/
2629dc3abcbeSRaghu Vatsavayi 	reg = 0x29220;
2630dc3abcbeSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%08x] (SLI_PKT_BIST_STATUS): %016llx\n",
2631dc3abcbeSRaghu Vatsavayi 		       reg, (u64)octeon_read_csr64(oct, reg));
2632dc3abcbeSRaghu Vatsavayi 
2633dc3abcbeSRaghu Vatsavayi 	/*PF only*/
2634dc3abcbeSRaghu Vatsavayi 	if (pf_num == 0) {
2635dc3abcbeSRaghu Vatsavayi 		/*0x29260*/
2636dc3abcbeSRaghu Vatsavayi 		reg = CN23XX_SLI_OUT_BP_EN_W1S;
2637dc3abcbeSRaghu Vatsavayi 		len += sprintf(s + len,
2638dc3abcbeSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT_OUT_BP_EN_W1S):  %016llx\n",
2639dc3abcbeSRaghu Vatsavayi 			       reg, (u64)octeon_read_csr64(oct, reg));
2640dc3abcbeSRaghu Vatsavayi 	} else if (pf_num == 1) {
2641dc3abcbeSRaghu Vatsavayi 		/*0x29270*/
2642dc3abcbeSRaghu Vatsavayi 		reg = CN23XX_SLI_OUT_BP_EN2_W1S;
2643dc3abcbeSRaghu Vatsavayi 		len += sprintf(s + len,
2644dc3abcbeSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT_OUT_BP_EN2_W1S): %016llx\n",
2645dc3abcbeSRaghu Vatsavayi 			       reg, (u64)octeon_read_csr64(oct, reg));
2646dc3abcbeSRaghu Vatsavayi 	}
2647dc3abcbeSRaghu Vatsavayi 
2648dc3abcbeSRaghu Vatsavayi 	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
2649dc3abcbeSRaghu Vatsavayi 		reg = CN23XX_SLI_OQ_BUFF_INFO_SIZE(i);
2650dc3abcbeSRaghu Vatsavayi 		len +=
2651dc3abcbeSRaghu Vatsavayi 		    sprintf(s + len, "\n[%08x] (SLI_PKT%d_OUT_SIZE): %016llx\n",
2652dc3abcbeSRaghu Vatsavayi 			    reg, i, (u64)octeon_read_csr64(oct, reg));
2653dc3abcbeSRaghu Vatsavayi 	}
2654dc3abcbeSRaghu Vatsavayi 
2655dc3abcbeSRaghu Vatsavayi 	/*0x10040*/
2656dc3abcbeSRaghu Vatsavayi 	for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
2657dc3abcbeSRaghu Vatsavayi 		reg = CN23XX_SLI_IQ_INSTR_COUNT64(i);
2658dc3abcbeSRaghu Vatsavayi 		len += sprintf(s + len,
2659dc3abcbeSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",
2660dc3abcbeSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2661dc3abcbeSRaghu Vatsavayi 	}
2662dc3abcbeSRaghu Vatsavayi 
2663dc3abcbeSRaghu Vatsavayi 	/*0x10080*/
2664dc3abcbeSRaghu Vatsavayi 	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
2665dc3abcbeSRaghu Vatsavayi 		reg = CN23XX_SLI_OQ_PKTS_CREDIT(i);
2666dc3abcbeSRaghu Vatsavayi 		len += sprintf(s + len,
2667dc3abcbeSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016llx\n",
2668dc3abcbeSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2669dc3abcbeSRaghu Vatsavayi 	}
2670dc3abcbeSRaghu Vatsavayi 
2671dc3abcbeSRaghu Vatsavayi 	/*0x10090*/
2672dc3abcbeSRaghu Vatsavayi 	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
2673dc3abcbeSRaghu Vatsavayi 		reg = CN23XX_SLI_OQ_SIZE(i);
2674dc3abcbeSRaghu Vatsavayi 		len += sprintf(
2675dc3abcbeSRaghu Vatsavayi 		    s + len, "\n[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016llx\n",
2676dc3abcbeSRaghu Vatsavayi 		    reg, i, (u64)octeon_read_csr64(oct, reg));
2677dc3abcbeSRaghu Vatsavayi 	}
2678dc3abcbeSRaghu Vatsavayi 
2679dc3abcbeSRaghu Vatsavayi 	/*0x10050*/
2680dc3abcbeSRaghu Vatsavayi 	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
2681dc3abcbeSRaghu Vatsavayi 		reg = CN23XX_SLI_OQ_PKT_CONTROL(i);
2682dc3abcbeSRaghu Vatsavayi 		len += sprintf(
2683dc3abcbeSRaghu Vatsavayi 			s + len,
2684dc3abcbeSRaghu Vatsavayi 			"\n[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016llx\n",
2685dc3abcbeSRaghu Vatsavayi 			reg, i, (u64)octeon_read_csr64(oct, reg));
2686dc3abcbeSRaghu Vatsavayi 	}
2687dc3abcbeSRaghu Vatsavayi 
2688dc3abcbeSRaghu Vatsavayi 	/*0x10070*/
2689dc3abcbeSRaghu Vatsavayi 	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
2690dc3abcbeSRaghu Vatsavayi 		reg = CN23XX_SLI_OQ_BASE_ADDR64(i);
2691dc3abcbeSRaghu Vatsavayi 		len += sprintf(s + len,
2692dc3abcbeSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_SLIST_BADDR): %016llx\n",
2693dc3abcbeSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2694dc3abcbeSRaghu Vatsavayi 	}
2695dc3abcbeSRaghu Vatsavayi 
2696dc3abcbeSRaghu Vatsavayi 	/*0x100a0*/
2697dc3abcbeSRaghu Vatsavayi 	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
2698dc3abcbeSRaghu Vatsavayi 		reg = CN23XX_SLI_OQ_PKT_INT_LEVELS(i);
2699dc3abcbeSRaghu Vatsavayi 		len += sprintf(s + len,
2700dc3abcbeSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_INT_LEVELS): %016llx\n",
2701dc3abcbeSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2702dc3abcbeSRaghu Vatsavayi 	}
2703dc3abcbeSRaghu Vatsavayi 
2704dc3abcbeSRaghu Vatsavayi 	/*0x100b0*/
2705dc3abcbeSRaghu Vatsavayi 	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
2706dc3abcbeSRaghu Vatsavayi 		reg = CN23XX_SLI_OQ_PKTS_SENT(i);
2707dc3abcbeSRaghu Vatsavayi 		len += sprintf(s + len, "\n[%08x] (SLI_PKT%d_CNTS): %016llx\n",
2708dc3abcbeSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2709dc3abcbeSRaghu Vatsavayi 	}
2710dc3abcbeSRaghu Vatsavayi 
2711dc3abcbeSRaghu Vatsavayi 	/*0x100c0*/
2712dc3abcbeSRaghu Vatsavayi 	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
2713dc3abcbeSRaghu Vatsavayi 		reg = 0x100c0 + i * CN23XX_OQ_OFFSET;
2714dc3abcbeSRaghu Vatsavayi 		len += sprintf(s + len,
2715dc3abcbeSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_ERROR_INFO): %016llx\n",
2716dc3abcbeSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2717dc3abcbeSRaghu Vatsavayi 
2718dc3abcbeSRaghu Vatsavayi 		/*0x10000*/
2719dc3abcbeSRaghu Vatsavayi 		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
2720dc3abcbeSRaghu Vatsavayi 			reg = CN23XX_SLI_IQ_PKT_CONTROL64(i);
2721dc3abcbeSRaghu Vatsavayi 			len += sprintf(
2722dc3abcbeSRaghu Vatsavayi 				s + len,
2723dc3abcbeSRaghu Vatsavayi 				"\n[%08x] (SLI_PKT%d_INPUT_CONTROL): %016llx\n",
2724dc3abcbeSRaghu Vatsavayi 				reg, i, (u64)octeon_read_csr64(oct, reg));
2725dc3abcbeSRaghu Vatsavayi 		}
2726dc3abcbeSRaghu Vatsavayi 
2727dc3abcbeSRaghu Vatsavayi 		/*0x10010*/
2728dc3abcbeSRaghu Vatsavayi 		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
2729dc3abcbeSRaghu Vatsavayi 			reg = CN23XX_SLI_IQ_BASE_ADDR64(i);
2730dc3abcbeSRaghu Vatsavayi 			len += sprintf(
2731dc3abcbeSRaghu Vatsavayi 			    s + len,
2732dc3abcbeSRaghu Vatsavayi 			    "\n[%08x] (SLI_PKT%d_INSTR_BADDR): %016llx\n", reg,
2733dc3abcbeSRaghu Vatsavayi 			    i, (u64)octeon_read_csr64(oct, reg));
2734dc3abcbeSRaghu Vatsavayi 		}
2735dc3abcbeSRaghu Vatsavayi 
2736dc3abcbeSRaghu Vatsavayi 		/*0x10020*/
2737dc3abcbeSRaghu Vatsavayi 		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
2738dc3abcbeSRaghu Vatsavayi 			reg = CN23XX_SLI_IQ_DOORBELL(i);
2739dc3abcbeSRaghu Vatsavayi 			len += sprintf(
2740dc3abcbeSRaghu Vatsavayi 			    s + len,
2741dc3abcbeSRaghu Vatsavayi 			    "\n[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016llx\n",
2742dc3abcbeSRaghu Vatsavayi 			    reg, i, (u64)octeon_read_csr64(oct, reg));
2743dc3abcbeSRaghu Vatsavayi 		}
2744dc3abcbeSRaghu Vatsavayi 
2745dc3abcbeSRaghu Vatsavayi 		/*0x10030*/
2746dc3abcbeSRaghu Vatsavayi 		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
2747dc3abcbeSRaghu Vatsavayi 			reg = CN23XX_SLI_IQ_SIZE(i);
2748dc3abcbeSRaghu Vatsavayi 			len += sprintf(
2749dc3abcbeSRaghu Vatsavayi 			    s + len,
2750dc3abcbeSRaghu Vatsavayi 			    "\n[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016llx\n",
2751dc3abcbeSRaghu Vatsavayi 			    reg, i, (u64)octeon_read_csr64(oct, reg));
2752dc3abcbeSRaghu Vatsavayi 		}
2753dc3abcbeSRaghu Vatsavayi 
2754dc3abcbeSRaghu Vatsavayi 		/*0x10040*/
2755dc3abcbeSRaghu Vatsavayi 		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++)
2756dc3abcbeSRaghu Vatsavayi 			reg = CN23XX_SLI_IQ_INSTR_COUNT64(i);
2757dc3abcbeSRaghu Vatsavayi 		len += sprintf(s + len,
2758dc3abcbeSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",
2759dc3abcbeSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2760dc3abcbeSRaghu Vatsavayi 	}
2761dc3abcbeSRaghu Vatsavayi 
2762dc3abcbeSRaghu Vatsavayi 	return len;
2763dc3abcbeSRaghu Vatsavayi }
2764f21fb3edSRaghu Vatsavayi 
cn23xx_vf_read_csr_reg(char * s,struct octeon_device * oct)2765d8ab848cSRaghu Vatsavayi static int cn23xx_vf_read_csr_reg(char *s, struct octeon_device *oct)
2766d8ab848cSRaghu Vatsavayi {
2767d8ab848cSRaghu Vatsavayi 	int len = 0;
2768d8ab848cSRaghu Vatsavayi 	u32 reg;
2769d8ab848cSRaghu Vatsavayi 	int i;
2770d8ab848cSRaghu Vatsavayi 
2771d8ab848cSRaghu Vatsavayi 	/* PCI  Window Registers */
2772d8ab848cSRaghu Vatsavayi 
2773d8ab848cSRaghu Vatsavayi 	len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n");
2774d8ab848cSRaghu Vatsavayi 
2775d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2776d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_OQ_BUFF_INFO_SIZE(i);
2777d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2778d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_OUT_SIZE): %016llx\n",
2779d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2780d8ab848cSRaghu Vatsavayi 	}
2781d8ab848cSRaghu Vatsavayi 
2782d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2783d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_IQ_INSTR_COUNT64(i);
2784d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2785d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",
2786d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2787d8ab848cSRaghu Vatsavayi 	}
2788d8ab848cSRaghu Vatsavayi 
2789d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2790d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_OQ_PKTS_CREDIT(i);
2791d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2792d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016llx\n",
2793d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2794d8ab848cSRaghu Vatsavayi 	}
2795d8ab848cSRaghu Vatsavayi 
2796d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2797d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_OQ_SIZE(i);
2798d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2799d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016llx\n",
2800d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2801d8ab848cSRaghu Vatsavayi 	}
2802d8ab848cSRaghu Vatsavayi 
2803d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2804d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_OQ_PKT_CONTROL(i);
2805d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2806d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016llx\n",
2807d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2808d8ab848cSRaghu Vatsavayi 	}
2809d8ab848cSRaghu Vatsavayi 
2810d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2811d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_OQ_BASE_ADDR64(i);
2812d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2813d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_SLIST_BADDR): %016llx\n",
2814d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2815d8ab848cSRaghu Vatsavayi 	}
2816d8ab848cSRaghu Vatsavayi 
2817d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2818d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(i);
2819d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2820d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_INT_LEVELS): %016llx\n",
2821d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2822d8ab848cSRaghu Vatsavayi 	}
2823d8ab848cSRaghu Vatsavayi 
2824d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2825d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_OQ_PKTS_SENT(i);
2826d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len, "\n[%08x] (SLI_PKT%d_CNTS): %016llx\n",
2827d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2828d8ab848cSRaghu Vatsavayi 	}
2829d8ab848cSRaghu Vatsavayi 
2830d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2831d8ab848cSRaghu Vatsavayi 		reg = 0x100c0 + i * CN23XX_VF_OQ_OFFSET;
2832d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2833d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_ERROR_INFO): %016llx\n",
2834d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2835d8ab848cSRaghu Vatsavayi 	}
2836d8ab848cSRaghu Vatsavayi 
2837d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2838d8ab848cSRaghu Vatsavayi 		reg = 0x100d0 + i * CN23XX_VF_IQ_OFFSET;
2839d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2840d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_VF_INT_SUM): %016llx\n",
2841d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2842d8ab848cSRaghu Vatsavayi 	}
2843d8ab848cSRaghu Vatsavayi 
2844d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2845d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_IQ_PKT_CONTROL64(i);
2846d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2847d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_INPUT_CONTROL): %016llx\n",
2848d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2849d8ab848cSRaghu Vatsavayi 	}
2850d8ab848cSRaghu Vatsavayi 
2851d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2852d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_IQ_BASE_ADDR64(i);
2853d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2854d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_INSTR_BADDR): %016llx\n",
2855d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2856d8ab848cSRaghu Vatsavayi 	}
2857d8ab848cSRaghu Vatsavayi 
2858d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2859d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_IQ_DOORBELL(i);
2860d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2861d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016llx\n",
2862d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2863d8ab848cSRaghu Vatsavayi 	}
2864d8ab848cSRaghu Vatsavayi 
2865d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2866d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_IQ_SIZE(i);
2867d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2868d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016llx\n",
2869d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2870d8ab848cSRaghu Vatsavayi 	}
2871d8ab848cSRaghu Vatsavayi 
2872d8ab848cSRaghu Vatsavayi 	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {
2873d8ab848cSRaghu Vatsavayi 		reg = CN23XX_VF_SLI_IQ_INSTR_COUNT64(i);
2874d8ab848cSRaghu Vatsavayi 		len += sprintf(s + len,
2875d8ab848cSRaghu Vatsavayi 			       "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",
2876d8ab848cSRaghu Vatsavayi 			       reg, i, (u64)octeon_read_csr64(oct, reg));
2877d8ab848cSRaghu Vatsavayi 	}
2878d8ab848cSRaghu Vatsavayi 
2879d8ab848cSRaghu Vatsavayi 	return len;
2880d8ab848cSRaghu Vatsavayi }
2881d8ab848cSRaghu Vatsavayi 
cn6xxx_read_csr_reg(char * s,struct octeon_device * oct)2882f21fb3edSRaghu Vatsavayi static int cn6xxx_read_csr_reg(char *s, struct octeon_device *oct)
2883f21fb3edSRaghu Vatsavayi {
2884f21fb3edSRaghu Vatsavayi 	u32 reg;
2885f21fb3edSRaghu Vatsavayi 	int i, len = 0;
2886f21fb3edSRaghu Vatsavayi 
2887f21fb3edSRaghu Vatsavayi 	/* PCI  Window Registers */
2888f21fb3edSRaghu Vatsavayi 
2889f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n");
2890f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_WIN_WR_ADDR_LO;
2891f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%02x] (WIN_WR_ADDR_LO): %08x\n",
2892f21fb3edSRaghu Vatsavayi 		       CN6XXX_WIN_WR_ADDR_LO, octeon_read_csr(oct, reg));
2893f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_WIN_WR_ADDR_HI;
2894f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%02x] (WIN_WR_ADDR_HI): %08x\n",
2895f21fb3edSRaghu Vatsavayi 		       CN6XXX_WIN_WR_ADDR_HI, octeon_read_csr(oct, reg));
2896f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_WIN_RD_ADDR_LO;
2897f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%02x] (WIN_RD_ADDR_LO): %08x\n",
2898f21fb3edSRaghu Vatsavayi 		       CN6XXX_WIN_RD_ADDR_LO, octeon_read_csr(oct, reg));
2899f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_WIN_RD_ADDR_HI;
2900f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%02x] (WIN_RD_ADDR_HI): %08x\n",
2901f21fb3edSRaghu Vatsavayi 		       CN6XXX_WIN_RD_ADDR_HI, octeon_read_csr(oct, reg));
2902f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_WIN_WR_DATA_LO;
2903f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%02x] (WIN_WR_DATA_LO): %08x\n",
2904f21fb3edSRaghu Vatsavayi 		       CN6XXX_WIN_WR_DATA_LO, octeon_read_csr(oct, reg));
2905f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_WIN_WR_DATA_HI;
2906f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%02x] (WIN_WR_DATA_HI): %08x\n",
2907f21fb3edSRaghu Vatsavayi 		       CN6XXX_WIN_WR_DATA_HI, octeon_read_csr(oct, reg));
2908f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%02x] (WIN_WR_MASK_REG): %08x\n",
2909f21fb3edSRaghu Vatsavayi 		       CN6XXX_WIN_WR_MASK_REG,
2910f21fb3edSRaghu Vatsavayi 		       octeon_read_csr(oct, CN6XXX_WIN_WR_MASK_REG));
2911f21fb3edSRaghu Vatsavayi 
2912f21fb3edSRaghu Vatsavayi 	/* PCI  Interrupt Register */
2913f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%x] (INT_ENABLE PORT 0): %08x\n",
2914f21fb3edSRaghu Vatsavayi 		       CN6XXX_SLI_INT_ENB64_PORT0, octeon_read_csr(oct,
2915f21fb3edSRaghu Vatsavayi 						CN6XXX_SLI_INT_ENB64_PORT0));
2916f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%x] (INT_ENABLE PORT 1): %08x\n",
2917f21fb3edSRaghu Vatsavayi 		       CN6XXX_SLI_INT_ENB64_PORT1,
2918f21fb3edSRaghu Vatsavayi 		       octeon_read_csr(oct, CN6XXX_SLI_INT_ENB64_PORT1));
2919f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%x] (INT_SUM): %08x\n", CN6XXX_SLI_INT_SUM64,
2920f21fb3edSRaghu Vatsavayi 		       octeon_read_csr(oct, CN6XXX_SLI_INT_SUM64));
2921f21fb3edSRaghu Vatsavayi 
2922f21fb3edSRaghu Vatsavayi 	/* PCI  Output queue registers */
2923f21fb3edSRaghu Vatsavayi 	for (i = 0; i < oct->num_oqs; i++) {
2924f21fb3edSRaghu Vatsavayi 		reg = CN6XXX_SLI_OQ_PKTS_SENT(i);
2925f21fb3edSRaghu Vatsavayi 		len += sprintf(s + len, "\n[%x] (PKTS_SENT_%d): %08x\n",
2926f21fb3edSRaghu Vatsavayi 			       reg, i, octeon_read_csr(oct, reg));
2927f21fb3edSRaghu Vatsavayi 		reg = CN6XXX_SLI_OQ_PKTS_CREDIT(i);
2928f21fb3edSRaghu Vatsavayi 		len += sprintf(s + len, "[%x] (PKT_CREDITS_%d): %08x\n",
2929f21fb3edSRaghu Vatsavayi 			       reg, i, octeon_read_csr(oct, reg));
2930f21fb3edSRaghu Vatsavayi 	}
2931f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_SLI_OQ_INT_LEVEL_PKTS;
2932f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%x] (PKTS_SENT_INT_LEVEL): %08x\n",
2933f21fb3edSRaghu Vatsavayi 		       reg, octeon_read_csr(oct, reg));
2934f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_SLI_OQ_INT_LEVEL_TIME;
2935f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%x] (PKTS_SENT_TIME): %08x\n",
2936f21fb3edSRaghu Vatsavayi 		       reg, octeon_read_csr(oct, reg));
2937f21fb3edSRaghu Vatsavayi 
2938f21fb3edSRaghu Vatsavayi 	/* PCI  Input queue registers */
2939f21fb3edSRaghu Vatsavayi 	for (i = 0; i <= 3; i++) {
2940f21fb3edSRaghu Vatsavayi 		u32 reg;
2941f21fb3edSRaghu Vatsavayi 
2942f21fb3edSRaghu Vatsavayi 		reg = CN6XXX_SLI_IQ_DOORBELL(i);
2943f21fb3edSRaghu Vatsavayi 		len += sprintf(s + len, "\n[%x] (INSTR_DOORBELL_%d): %08x\n",
2944f21fb3edSRaghu Vatsavayi 			       reg, i, octeon_read_csr(oct, reg));
2945f21fb3edSRaghu Vatsavayi 		reg = CN6XXX_SLI_IQ_INSTR_COUNT(i);
2946f21fb3edSRaghu Vatsavayi 		len += sprintf(s + len, "[%x] (INSTR_COUNT_%d): %08x\n",
2947f21fb3edSRaghu Vatsavayi 			       reg, i, octeon_read_csr(oct, reg));
2948f21fb3edSRaghu Vatsavayi 	}
2949f21fb3edSRaghu Vatsavayi 
2950f21fb3edSRaghu Vatsavayi 	/* PCI  DMA registers */
2951f21fb3edSRaghu Vatsavayi 
2952f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%x] (DMA_CNT_0): %08x\n",
2953f21fb3edSRaghu Vatsavayi 		       CN6XXX_DMA_CNT(0),
2954f21fb3edSRaghu Vatsavayi 		       octeon_read_csr(oct, CN6XXX_DMA_CNT(0)));
2955f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_DMA_PKT_INT_LEVEL(0);
2956f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%x] (DMA_INT_LEV_0): %08x\n",
2957f21fb3edSRaghu Vatsavayi 		       CN6XXX_DMA_PKT_INT_LEVEL(0), octeon_read_csr(oct, reg));
2958f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_DMA_TIME_INT_LEVEL(0);
2959f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%x] (DMA_TIME_0): %08x\n",
2960f21fb3edSRaghu Vatsavayi 		       CN6XXX_DMA_TIME_INT_LEVEL(0),
2961f21fb3edSRaghu Vatsavayi 		       octeon_read_csr(oct, reg));
2962f21fb3edSRaghu Vatsavayi 
2963f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "\n[%x] (DMA_CNT_1): %08x\n",
2964f21fb3edSRaghu Vatsavayi 		       CN6XXX_DMA_CNT(1),
2965f21fb3edSRaghu Vatsavayi 		       octeon_read_csr(oct, CN6XXX_DMA_CNT(1)));
2966f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_DMA_PKT_INT_LEVEL(1);
2967f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%x] (DMA_INT_LEV_1): %08x\n",
2968f21fb3edSRaghu Vatsavayi 		       CN6XXX_DMA_PKT_INT_LEVEL(1),
2969f21fb3edSRaghu Vatsavayi 		       octeon_read_csr(oct, reg));
2970f21fb3edSRaghu Vatsavayi 	reg = CN6XXX_DMA_PKT_INT_LEVEL(1);
2971f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "[%x] (DMA_TIME_1): %08x\n",
2972f21fb3edSRaghu Vatsavayi 		       CN6XXX_DMA_TIME_INT_LEVEL(1),
2973f21fb3edSRaghu Vatsavayi 		       octeon_read_csr(oct, reg));
2974f21fb3edSRaghu Vatsavayi 
2975f21fb3edSRaghu Vatsavayi 	/* PCI  Index registers */
2976f21fb3edSRaghu Vatsavayi 
2977f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len, "\n");
2978f21fb3edSRaghu Vatsavayi 
2979f21fb3edSRaghu Vatsavayi 	for (i = 0; i < 16; i++) {
2980f21fb3edSRaghu Vatsavayi 		reg = lio_pci_readq(oct, CN6XXX_BAR1_REG(i, oct->pcie_port));
2981f21fb3edSRaghu Vatsavayi 		len += sprintf(s + len, "[%llx] (BAR1_INDEX_%02d): %08x\n",
2982f21fb3edSRaghu Vatsavayi 			       CN6XXX_BAR1_REG(i, oct->pcie_port), i, reg);
2983f21fb3edSRaghu Vatsavayi 	}
2984f21fb3edSRaghu Vatsavayi 
2985f21fb3edSRaghu Vatsavayi 	return len;
2986f21fb3edSRaghu Vatsavayi }
2987f21fb3edSRaghu Vatsavayi 
cn6xxx_read_config_reg(char * s,struct octeon_device * oct)2988f21fb3edSRaghu Vatsavayi static int cn6xxx_read_config_reg(char *s, struct octeon_device *oct)
2989f21fb3edSRaghu Vatsavayi {
2990f21fb3edSRaghu Vatsavayi 	u32 val;
2991f21fb3edSRaghu Vatsavayi 	int i, len = 0;
2992f21fb3edSRaghu Vatsavayi 
2993f21fb3edSRaghu Vatsavayi 	/* PCI CONFIG Registers */
2994f21fb3edSRaghu Vatsavayi 
2995f21fb3edSRaghu Vatsavayi 	len += sprintf(s + len,
2996f21fb3edSRaghu Vatsavayi 		       "\n\t Octeon Config space Registers\n\n");
2997f21fb3edSRaghu Vatsavayi 
2998f21fb3edSRaghu Vatsavayi 	for (i = 0; i <= 13; i++) {
2999f21fb3edSRaghu Vatsavayi 		pci_read_config_dword(oct->pci_dev, (i * 4), &val);
3000f21fb3edSRaghu Vatsavayi 		len += sprintf(s + len, "[0x%x] (Config[%d]): 0x%08x\n",
3001f21fb3edSRaghu Vatsavayi 			       (i * 4), i, val);
3002f21fb3edSRaghu Vatsavayi 	}
3003f21fb3edSRaghu Vatsavayi 
3004f21fb3edSRaghu Vatsavayi 	for (i = 30; i <= 34; i++) {
3005f21fb3edSRaghu Vatsavayi 		pci_read_config_dword(oct->pci_dev, (i * 4), &val);
3006f21fb3edSRaghu Vatsavayi 		len += sprintf(s + len, "[0x%x] (Config[%d]): 0x%08x\n",
3007f21fb3edSRaghu Vatsavayi 			       (i * 4), i, val);
3008f21fb3edSRaghu Vatsavayi 	}
3009f21fb3edSRaghu Vatsavayi 
3010f21fb3edSRaghu Vatsavayi 	return len;
3011f21fb3edSRaghu Vatsavayi }
3012f21fb3edSRaghu Vatsavayi 
3013f21fb3edSRaghu Vatsavayi /*  Return register dump user app.  */
lio_get_regs(struct net_device * dev,struct ethtool_regs * regs,void * regbuf)3014f21fb3edSRaghu Vatsavayi static void lio_get_regs(struct net_device *dev,
3015f21fb3edSRaghu Vatsavayi 			 struct ethtool_regs *regs, void *regbuf)
3016f21fb3edSRaghu Vatsavayi {
3017f21fb3edSRaghu Vatsavayi 	struct lio *lio = GET_LIO(dev);
3018f21fb3edSRaghu Vatsavayi 	int len = 0;
3019f21fb3edSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
3020f21fb3edSRaghu Vatsavayi 
3021f21fb3edSRaghu Vatsavayi 	regs->version = OCT_ETHTOOL_REGSVER;
3022f21fb3edSRaghu Vatsavayi 
3023f21fb3edSRaghu Vatsavayi 	switch (oct->chip_id) {
3024dc3abcbeSRaghu Vatsavayi 	case OCTEON_CN23XX_PF_VID:
3025dc3abcbeSRaghu Vatsavayi 		memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN_23XX);
3026dc3abcbeSRaghu Vatsavayi 		len += cn23xx_read_csr_reg(regbuf + len, oct);
3027dc3abcbeSRaghu Vatsavayi 		break;
3028d8ab848cSRaghu Vatsavayi 	case OCTEON_CN23XX_VF_VID:
3029d8ab848cSRaghu Vatsavayi 		memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN_23XX_VF);
3030d8ab848cSRaghu Vatsavayi 		len += cn23xx_vf_read_csr_reg(regbuf + len, oct);
3031d8ab848cSRaghu Vatsavayi 		break;
3032f21fb3edSRaghu Vatsavayi 	case OCTEON_CN68XX:
3033f21fb3edSRaghu Vatsavayi 	case OCTEON_CN66XX:
3034a2c64b67SRaghu Vatsavayi 		memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN);
3035f21fb3edSRaghu Vatsavayi 		len += cn6xxx_read_csr_reg(regbuf + len, oct);
3036f21fb3edSRaghu Vatsavayi 		len += cn6xxx_read_config_reg(regbuf + len, oct);
3037f21fb3edSRaghu Vatsavayi 		break;
3038f21fb3edSRaghu Vatsavayi 	default:
3039f21fb3edSRaghu Vatsavayi 		dev_err(&oct->pci_dev->dev, "%s Unknown chipid: %d\n",
3040f21fb3edSRaghu Vatsavayi 			__func__, oct->chip_id);
3041f21fb3edSRaghu Vatsavayi 	}
3042f21fb3edSRaghu Vatsavayi }
3043f21fb3edSRaghu Vatsavayi 
lio_get_priv_flags(struct net_device * netdev)3044f5a20472SRaghu Vatsavayi static u32 lio_get_priv_flags(struct net_device *netdev)
3045f5a20472SRaghu Vatsavayi {
3046f5a20472SRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
3047f5a20472SRaghu Vatsavayi 
3048f5a20472SRaghu Vatsavayi 	return lio->oct_dev->priv_flags;
3049f5a20472SRaghu Vatsavayi }
3050f5a20472SRaghu Vatsavayi 
lio_set_priv_flags(struct net_device * netdev,u32 flags)3051f5a20472SRaghu Vatsavayi static int lio_set_priv_flags(struct net_device *netdev, u32 flags)
3052f5a20472SRaghu Vatsavayi {
3053f5a20472SRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
3054f5a20472SRaghu Vatsavayi 	bool intr_by_tx_bytes = !!(flags & (0x1 << OCT_PRIV_FLAG_TX_BYTES));
3055f5a20472SRaghu Vatsavayi 
3056f5a20472SRaghu Vatsavayi 	lio_set_priv_flag(lio->oct_dev, OCT_PRIV_FLAG_TX_BYTES,
3057f5a20472SRaghu Vatsavayi 			  intr_by_tx_bytes);
3058f5a20472SRaghu Vatsavayi 	return 0;
3059f5a20472SRaghu Vatsavayi }
3060f5a20472SRaghu Vatsavayi 
lio_get_fecparam(struct net_device * netdev,struct ethtool_fecparam * fec)306175b2c206SWeilin Chang static int lio_get_fecparam(struct net_device *netdev,
306275b2c206SWeilin Chang 			    struct ethtool_fecparam *fec)
306375b2c206SWeilin Chang {
306475b2c206SWeilin Chang 	struct lio *lio = GET_LIO(netdev);
306575b2c206SWeilin Chang 	struct octeon_device *oct = lio->oct_dev;
306675b2c206SWeilin Chang 
306775b2c206SWeilin Chang 	fec->active_fec = ETHTOOL_FEC_NONE;
306875b2c206SWeilin Chang 	fec->fec = ETHTOOL_FEC_NONE;
306975b2c206SWeilin Chang 
307075b2c206SWeilin Chang 	if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID ||
307175b2c206SWeilin Chang 	    oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) {
307275b2c206SWeilin Chang 		if (oct->no_speed_setting == 1)
307375b2c206SWeilin Chang 			return 0;
307475b2c206SWeilin Chang 
307575b2c206SWeilin Chang 		liquidio_get_fec(lio);
307675b2c206SWeilin Chang 		fec->fec = (ETHTOOL_FEC_RS | ETHTOOL_FEC_OFF);
307775b2c206SWeilin Chang 		if (oct->props[lio->ifidx].fec == 1)
307875b2c206SWeilin Chang 			fec->active_fec = ETHTOOL_FEC_RS;
307975b2c206SWeilin Chang 		else
308075b2c206SWeilin Chang 			fec->active_fec = ETHTOOL_FEC_OFF;
308175b2c206SWeilin Chang 	}
308275b2c206SWeilin Chang 
308375b2c206SWeilin Chang 	return 0;
308475b2c206SWeilin Chang }
308575b2c206SWeilin Chang 
lio_set_fecparam(struct net_device * netdev,struct ethtool_fecparam * fec)308675b2c206SWeilin Chang static int lio_set_fecparam(struct net_device *netdev,
308775b2c206SWeilin Chang 			    struct ethtool_fecparam *fec)
308875b2c206SWeilin Chang {
308975b2c206SWeilin Chang 	struct lio *lio = GET_LIO(netdev);
309075b2c206SWeilin Chang 	struct octeon_device *oct = lio->oct_dev;
309175b2c206SWeilin Chang 
309275b2c206SWeilin Chang 	if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID ||
309375b2c206SWeilin Chang 	    oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) {
309475b2c206SWeilin Chang 		if (oct->no_speed_setting == 1)
309575b2c206SWeilin Chang 			return -EOPNOTSUPP;
309675b2c206SWeilin Chang 
309775b2c206SWeilin Chang 		if (fec->fec & ETHTOOL_FEC_OFF)
309875b2c206SWeilin Chang 			liquidio_set_fec(lio, 0);
309975b2c206SWeilin Chang 		else if (fec->fec & ETHTOOL_FEC_RS)
310075b2c206SWeilin Chang 			liquidio_set_fec(lio, 1);
310175b2c206SWeilin Chang 		else
310275b2c206SWeilin Chang 			return -EOPNOTSUPP;
310375b2c206SWeilin Chang 	} else {
310475b2c206SWeilin Chang 		return -EOPNOTSUPP;
310575b2c206SWeilin Chang 	}
310675b2c206SWeilin Chang 
310775b2c206SWeilin Chang 	return 0;
310875b2c206SWeilin Chang }
310975b2c206SWeilin Chang 
3110812df69bSJakub Kicinski #define LIO_ETHTOOL_COALESCE	(ETHTOOL_COALESCE_RX_USECS |		\
3111812df69bSJakub Kicinski 				 ETHTOOL_COALESCE_MAX_FRAMES |		\
3112812df69bSJakub Kicinski 				 ETHTOOL_COALESCE_USE_ADAPTIVE |	\
3113812df69bSJakub Kicinski 				 ETHTOOL_COALESCE_RX_MAX_FRAMES_LOW |	\
3114812df69bSJakub Kicinski 				 ETHTOOL_COALESCE_TX_MAX_FRAMES_LOW |	\
3115812df69bSJakub Kicinski 				 ETHTOOL_COALESCE_RX_MAX_FRAMES_HIGH |	\
3116812df69bSJakub Kicinski 				 ETHTOOL_COALESCE_TX_MAX_FRAMES_HIGH |	\
3117812df69bSJakub Kicinski 				 ETHTOOL_COALESCE_PKT_RATE_RX_USECS)
3118812df69bSJakub Kicinski 
3119f21fb3edSRaghu Vatsavayi static const struct ethtool_ops lio_ethtool_ops = {
3120812df69bSJakub Kicinski 	.supported_coalesce_params = LIO_ETHTOOL_COALESCE,
3121d8ab848cSRaghu Vatsavayi 	.get_link_ksettings	= lio_get_link_ksettings,
312218b338f5SWeilin Chang 	.set_link_ksettings	= lio_set_link_ksettings,
312375b2c206SWeilin Chang 	.get_fecparam		= lio_get_fecparam,
312475b2c206SWeilin Chang 	.set_fecparam		= lio_set_fecparam,
3125f21fb3edSRaghu Vatsavayi 	.get_link		= ethtool_op_get_link,
3126f21fb3edSRaghu Vatsavayi 	.get_drvinfo		= lio_get_drvinfo,
3127f21fb3edSRaghu Vatsavayi 	.get_ringparam		= lio_ethtool_get_ringparam,
3128d18ca7dfSIntiyaz Basha 	.set_ringparam		= lio_ethtool_set_ringparam,
3129f21fb3edSRaghu Vatsavayi 	.get_channels		= lio_ethtool_get_channels,
3130a82457f1SIntiyaz Basha 	.set_channels		= lio_ethtool_set_channels,
3131f21fb3edSRaghu Vatsavayi 	.set_phys_id		= lio_set_phys_id,
3132f21fb3edSRaghu Vatsavayi 	.get_eeprom_len		= lio_get_eeprom_len,
3133f21fb3edSRaghu Vatsavayi 	.get_eeprom		= lio_get_eeprom,
3134f21fb3edSRaghu Vatsavayi 	.get_strings		= lio_get_strings,
3135f21fb3edSRaghu Vatsavayi 	.get_ethtool_stats	= lio_get_ethtool_stats,
3136f21fb3edSRaghu Vatsavayi 	.get_pauseparam		= lio_get_pauseparam,
313730136395SRaghu Vatsavayi 	.set_pauseparam		= lio_set_pauseparam,
3138f21fb3edSRaghu Vatsavayi 	.get_regs_len		= lio_get_regs_len,
3139f21fb3edSRaghu Vatsavayi 	.get_regs		= lio_get_regs,
3140f21fb3edSRaghu Vatsavayi 	.get_msglevel		= lio_get_msglevel,
3141f21fb3edSRaghu Vatsavayi 	.set_msglevel		= lio_set_msglevel,
3142f21fb3edSRaghu Vatsavayi 	.get_sset_count		= lio_get_sset_count,
3143d8ab848cSRaghu Vatsavayi 	.get_coalesce		= lio_get_intr_coalesce,
3144d8ab848cSRaghu Vatsavayi 	.set_coalesce		= lio_set_intr_coalesce,
3145d8ab848cSRaghu Vatsavayi 	.get_priv_flags		= lio_get_priv_flags,
3146d8ab848cSRaghu Vatsavayi 	.set_priv_flags		= lio_set_priv_flags,
3147d8ab848cSRaghu Vatsavayi 	.get_ts_info		= lio_get_ts_info,
3148d8ab848cSRaghu Vatsavayi };
3149d8ab848cSRaghu Vatsavayi 
3150d8ab848cSRaghu Vatsavayi static const struct ethtool_ops lio_vf_ethtool_ops = {
3151812df69bSJakub Kicinski 	.supported_coalesce_params = LIO_ETHTOOL_COALESCE,
3152d8ab848cSRaghu Vatsavayi 	.get_link_ksettings	= lio_get_link_ksettings,
3153d8ab848cSRaghu Vatsavayi 	.get_link		= ethtool_op_get_link,
3154d8ab848cSRaghu Vatsavayi 	.get_drvinfo		= lio_get_vf_drvinfo,
3155d8ab848cSRaghu Vatsavayi 	.get_ringparam		= lio_ethtool_get_ringparam,
3156d18ca7dfSIntiyaz Basha 	.set_ringparam          = lio_ethtool_set_ringparam,
3157d8ab848cSRaghu Vatsavayi 	.get_channels		= lio_ethtool_get_channels,
3158a82457f1SIntiyaz Basha 	.set_channels		= lio_ethtool_set_channels,
3159d8ab848cSRaghu Vatsavayi 	.get_strings		= lio_vf_get_strings,
3160d8ab848cSRaghu Vatsavayi 	.get_ethtool_stats	= lio_vf_get_ethtool_stats,
3161d8ab848cSRaghu Vatsavayi 	.get_regs_len		= lio_get_regs_len,
3162d8ab848cSRaghu Vatsavayi 	.get_regs		= lio_get_regs,
3163d8ab848cSRaghu Vatsavayi 	.get_msglevel		= lio_get_msglevel,
31647fa13653SDerek Chickles 	.set_msglevel		= lio_vf_set_msglevel,
3165d8ab848cSRaghu Vatsavayi 	.get_sset_count		= lio_vf_get_sset_count,
3166f21fb3edSRaghu Vatsavayi 	.get_coalesce		= lio_get_intr_coalesce,
3167f21fb3edSRaghu Vatsavayi 	.set_coalesce		= lio_set_intr_coalesce,
3168f5a20472SRaghu Vatsavayi 	.get_priv_flags		= lio_get_priv_flags,
3169f5a20472SRaghu Vatsavayi 	.set_priv_flags		= lio_set_priv_flags,
3170f21fb3edSRaghu Vatsavayi 	.get_ts_info		= lio_get_ts_info,
3171f21fb3edSRaghu Vatsavayi };
3172f21fb3edSRaghu Vatsavayi 
liquidio_set_ethtool_ops(struct net_device * netdev)3173f21fb3edSRaghu Vatsavayi void liquidio_set_ethtool_ops(struct net_device *netdev)
3174f21fb3edSRaghu Vatsavayi {
3175d8ab848cSRaghu Vatsavayi 	struct lio *lio = GET_LIO(netdev);
3176d8ab848cSRaghu Vatsavayi 	struct octeon_device *oct = lio->oct_dev;
3177d8ab848cSRaghu Vatsavayi 
3178d8ab848cSRaghu Vatsavayi 	if (OCTEON_CN23XX_VF(oct))
3179d8ab848cSRaghu Vatsavayi 		netdev->ethtool_ops = &lio_vf_ethtool_ops;
3180d8ab848cSRaghu Vatsavayi 	else
3181f21fb3edSRaghu Vatsavayi 		netdev->ethtool_ops = &lio_ethtool_ops;
3182f21fb3edSRaghu Vatsavayi }
3183*f71be9d0SMasahiro Yamada EXPORT_SYMBOL_GPL(liquidio_set_ethtool_ops);
3184