brintos

brintos / linux-shallow public Read only

0
0
Text · 89.4 KiB · c849e2c Raw
3184 lines · c
1/**********************************************************************2 * Author: Cavium, Inc.3 *4 * Contact: support@cavium.com5 *          Please include "LiquidIO" in the subject.6 *7 * Copyright (c) 2003-2016 Cavium, Inc.8 *9 * This file is free software; you can redistribute it and/or modify10 * it under the terms of the GNU General Public License, Version 2, as11 * published by the Free Software Foundation.12 *13 * This file is distributed in the hope that it will be useful, but14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or16 * NONINFRINGEMENT.  See the GNU General Public License for more details.17 ***********************************************************************/18#include <linux/ethtool.h>19#include <linux/netdevice.h>20#include <linux/net_tstamp.h>21#include <linux/pci.h>22#include "liquidio_common.h"23#include "octeon_droq.h"24#include "octeon_iq.h"25#include "response_manager.h"26#include "octeon_device.h"27#include "octeon_nic.h"28#include "octeon_main.h"29#include "octeon_network.h"30#include "cn66xx_regs.h"31#include "cn66xx_device.h"32#include "cn23xx_pf_device.h"33#include "cn23xx_vf_device.h"34 35static int lio_reset_queues(struct net_device *netdev, uint32_t num_qs);36 37struct oct_intrmod_resp {38	u64     rh;39	struct oct_intrmod_cfg intrmod;40	u64     status;41};42 43struct oct_mdio_cmd_resp {44	u64 rh;45	struct oct_mdio_cmd resp;46	u64 status;47};48 49#define OCT_MDIO45_RESP_SIZE   (sizeof(struct oct_mdio_cmd_resp))50 51/* Octeon's interface mode of operation */52enum {53	INTERFACE_MODE_DISABLED,54	INTERFACE_MODE_RGMII,55	INTERFACE_MODE_GMII,56	INTERFACE_MODE_SPI,57	INTERFACE_MODE_PCIE,58	INTERFACE_MODE_XAUI,59	INTERFACE_MODE_SGMII,60	INTERFACE_MODE_PICMG,61	INTERFACE_MODE_NPI,62	INTERFACE_MODE_LOOP,63	INTERFACE_MODE_SRIO,64	INTERFACE_MODE_ILK,65	INTERFACE_MODE_RXAUI,66	INTERFACE_MODE_QSGMII,67	INTERFACE_MODE_AGL,68	INTERFACE_MODE_XLAUI,69	INTERFACE_MODE_XFI,70	INTERFACE_MODE_10G_KR,71	INTERFACE_MODE_40G_KR4,72	INTERFACE_MODE_MIXED,73};74 75#define OCT_ETHTOOL_REGDUMP_LEN  409676#define OCT_ETHTOOL_REGDUMP_LEN_23XX  (4096 * 11)77#define OCT_ETHTOOL_REGDUMP_LEN_23XX_VF  (4096 * 2)78#define OCT_ETHTOOL_REGSVER  179 80/* statistics of PF */81static const char oct_stats_strings[][ETH_GSTRING_LEN] = {82	"rx_packets",83	"tx_packets",84	"rx_bytes",85	"tx_bytes",86	"rx_errors",87	"tx_errors",88	"rx_dropped",89	"tx_dropped",90 91	"tx_total_sent",92	"tx_total_fwd",93	"tx_err_pko",94	"tx_err_pki",95	"tx_err_link",96	"tx_err_drop",97 98	"tx_tso",99	"tx_tso_packets",100	"tx_tso_err",101	"tx_vxlan",102 103	"tx_mcast",104	"tx_bcast",105 106	"mac_tx_total_pkts",107	"mac_tx_total_bytes",108	"mac_tx_mcast_pkts",109	"mac_tx_bcast_pkts",110	"mac_tx_ctl_packets",111	"mac_tx_total_collisions",112	"mac_tx_one_collision",113	"mac_tx_multi_collision",114	"mac_tx_max_collision_fail",115	"mac_tx_max_deferral_fail",116	"mac_tx_fifo_err",117	"mac_tx_runts",118 119	"rx_total_rcvd",120	"rx_total_fwd",121	"rx_mcast",122	"rx_bcast",123	"rx_jabber_err",124	"rx_l2_err",125	"rx_frame_err",126	"rx_err_pko",127	"rx_err_link",128	"rx_err_drop",129 130	"rx_vxlan",131	"rx_vxlan_err",132 133	"rx_lro_pkts",134	"rx_lro_bytes",135	"rx_total_lro",136 137	"rx_lro_aborts",138	"rx_lro_aborts_port",139	"rx_lro_aborts_seq",140	"rx_lro_aborts_tsval",141	"rx_lro_aborts_timer",142	"rx_fwd_rate",143 144	"mac_rx_total_rcvd",145	"mac_rx_bytes",146	"mac_rx_total_bcst",147	"mac_rx_total_mcst",148	"mac_rx_runts",149	"mac_rx_ctl_packets",150	"mac_rx_fifo_err",151	"mac_rx_dma_drop",152	"mac_rx_fcs_err",153 154	"link_state_changes",155};156 157/* statistics of VF */158static const char oct_vf_stats_strings[][ETH_GSTRING_LEN] = {159	"rx_packets",160	"tx_packets",161	"rx_bytes",162	"tx_bytes",163	"rx_errors",164	"tx_errors",165	"rx_dropped",166	"tx_dropped",167	"rx_mcast",168	"tx_mcast",169	"rx_bcast",170	"tx_bcast",171	"link_state_changes",172};173 174/* statistics of host tx queue */175static const char oct_iq_stats_strings[][ETH_GSTRING_LEN] = {176	"packets",177	"bytes",178	"dropped",179	"iq_busy",180	"sgentry_sent",181 182	"fw_instr_posted",183	"fw_instr_processed",184	"fw_instr_dropped",185	"fw_bytes_sent",186 187	"tso",188	"vxlan",189	"txq_restart",190};191 192/* statistics of host rx queue */193static const char oct_droq_stats_strings[][ETH_GSTRING_LEN] = {194	"packets",195	"bytes",196	"dropped",197	"dropped_nomem",198	"dropped_toomany",199	"fw_dropped",200	"fw_pkts_received",201	"fw_bytes_received",202	"fw_dropped_nodispatch",203 204	"vxlan",205	"buffer_alloc_failure",206};207 208/* LiquidIO driver private flags */209static const char oct_priv_flags_strings[][ETH_GSTRING_LEN] = {210};211 212#define OCTNIC_NCMD_AUTONEG_ON  0x1213#define OCTNIC_NCMD_PHY_ON      0x2214 215static int lio_get_link_ksettings(struct net_device *netdev,216				  struct ethtool_link_ksettings *ecmd)217{218	struct lio *lio = GET_LIO(netdev);219	struct octeon_device *oct = lio->oct_dev;220	struct oct_link_info *linfo;221 222	linfo = &lio->linfo;223 224	ethtool_link_ksettings_zero_link_mode(ecmd, supported);225	ethtool_link_ksettings_zero_link_mode(ecmd, advertising);226 227	switch (linfo->link.s.phy_type) {228	case LIO_PHY_PORT_TP:229		ecmd->base.port = PORT_TP;230		ecmd->base.autoneg = AUTONEG_DISABLE;231		ethtool_link_ksettings_add_link_mode(ecmd, supported, TP);232		ethtool_link_ksettings_add_link_mode(ecmd, supported, Pause);233		ethtool_link_ksettings_add_link_mode(ecmd, supported,234						     10000baseT_Full);235 236		ethtool_link_ksettings_add_link_mode(ecmd, advertising, Pause);237		ethtool_link_ksettings_add_link_mode(ecmd, advertising,238						     10000baseT_Full);239 240		break;241 242	case LIO_PHY_PORT_FIBRE:243		if (linfo->link.s.if_mode == INTERFACE_MODE_XAUI ||244		    linfo->link.s.if_mode == INTERFACE_MODE_RXAUI ||245		    linfo->link.s.if_mode == INTERFACE_MODE_XLAUI ||246		    linfo->link.s.if_mode == INTERFACE_MODE_XFI) {247			dev_dbg(&oct->pci_dev->dev, "ecmd->base.transceiver is XCVR_EXTERNAL\n");248			ecmd->base.transceiver = XCVR_EXTERNAL;249		} else {250			dev_err(&oct->pci_dev->dev, "Unknown link interface mode: %d\n",251				linfo->link.s.if_mode);252		}253 254		ecmd->base.port = PORT_FIBRE;255		ecmd->base.autoneg = AUTONEG_DISABLE;256		ethtool_link_ksettings_add_link_mode(ecmd, supported, FIBRE);257 258		ethtool_link_ksettings_add_link_mode(ecmd, supported, Pause);259		ethtool_link_ksettings_add_link_mode(ecmd, advertising, Pause);260		if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID ||261		    oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) {262			if (OCTEON_CN23XX_PF(oct)) {263				ethtool_link_ksettings_add_link_mode264					(ecmd, supported, 25000baseSR_Full);265				ethtool_link_ksettings_add_link_mode266					(ecmd, supported, 25000baseKR_Full);267				ethtool_link_ksettings_add_link_mode268					(ecmd, supported, 25000baseCR_Full);269 270				if (oct->no_speed_setting == 0)  {271					ethtool_link_ksettings_add_link_mode272						(ecmd, supported,273						 10000baseSR_Full);274					ethtool_link_ksettings_add_link_mode275						(ecmd, supported,276						 10000baseKR_Full);277					ethtool_link_ksettings_add_link_mode278						(ecmd, supported,279						 10000baseCR_Full);280				}281 282				if (oct->no_speed_setting == 0) {283					liquidio_get_speed(lio);284					liquidio_get_fec(lio);285				} else {286					oct->speed_setting = 25;287				}288 289				if (oct->speed_setting == 10) {290					ethtool_link_ksettings_add_link_mode291						(ecmd, advertising,292						 10000baseSR_Full);293					ethtool_link_ksettings_add_link_mode294						(ecmd, advertising,295						 10000baseKR_Full);296					ethtool_link_ksettings_add_link_mode297						(ecmd, advertising,298						 10000baseCR_Full);299				}300				if (oct->speed_setting == 25) {301					ethtool_link_ksettings_add_link_mode302						(ecmd, advertising,303						 25000baseSR_Full);304					ethtool_link_ksettings_add_link_mode305						(ecmd, advertising,306						 25000baseKR_Full);307					ethtool_link_ksettings_add_link_mode308						(ecmd, advertising,309						 25000baseCR_Full);310				}311 312				if (oct->no_speed_setting)313					break;314 315				ethtool_link_ksettings_add_link_mode316					(ecmd, supported, FEC_RS);317				ethtool_link_ksettings_add_link_mode318					(ecmd, supported, FEC_NONE);319					/*FEC_OFF*/320				if (oct->props[lio->ifidx].fec == 1) {321					/* ETHTOOL_FEC_RS */322					ethtool_link_ksettings_add_link_mode323						(ecmd, advertising, FEC_RS);324				} else {325					/* ETHTOOL_FEC_OFF */326					ethtool_link_ksettings_add_link_mode327						(ecmd, advertising, FEC_NONE);328				}329			} else { /* VF */330				if (linfo->link.s.speed == 10000) {331					ethtool_link_ksettings_add_link_mode332						(ecmd, supported,333						 10000baseSR_Full);334					ethtool_link_ksettings_add_link_mode335						(ecmd, supported,336						 10000baseKR_Full);337					ethtool_link_ksettings_add_link_mode338						(ecmd, supported,339						 10000baseCR_Full);340 341					ethtool_link_ksettings_add_link_mode342						(ecmd, advertising,343						 10000baseSR_Full);344					ethtool_link_ksettings_add_link_mode345						(ecmd, advertising,346						 10000baseKR_Full);347					ethtool_link_ksettings_add_link_mode348						(ecmd, advertising,349						 10000baseCR_Full);350				}351 352				if (linfo->link.s.speed == 25000) {353					ethtool_link_ksettings_add_link_mode354						(ecmd, supported,355						 25000baseSR_Full);356					ethtool_link_ksettings_add_link_mode357						(ecmd, supported,358						 25000baseKR_Full);359					ethtool_link_ksettings_add_link_mode360						(ecmd, supported,361						 25000baseCR_Full);362 363					ethtool_link_ksettings_add_link_mode364						(ecmd, advertising,365						 25000baseSR_Full);366					ethtool_link_ksettings_add_link_mode367						(ecmd, advertising,368						 25000baseKR_Full);369					ethtool_link_ksettings_add_link_mode370						(ecmd, advertising,371						 25000baseCR_Full);372				}373			}374		} else {375			ethtool_link_ksettings_add_link_mode(ecmd, supported,376							     10000baseT_Full);377			ethtool_link_ksettings_add_link_mode(ecmd, advertising,378							     10000baseT_Full);379		}380		break;381	}382 383	if (linfo->link.s.link_up) {384		ecmd->base.speed = linfo->link.s.speed;385		ecmd->base.duplex = linfo->link.s.duplex;386	} else {387		ecmd->base.speed = SPEED_UNKNOWN;388		ecmd->base.duplex = DUPLEX_UNKNOWN;389	}390 391	return 0;392}393 394static int lio_set_link_ksettings(struct net_device *netdev,395				  const struct ethtool_link_ksettings *ecmd)396{397	const int speed = ecmd->base.speed;398	struct lio *lio = GET_LIO(netdev);399	struct oct_link_info *linfo;400	struct octeon_device *oct;401 402	oct = lio->oct_dev;403 404	linfo = &lio->linfo;405 406	if (!(oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID ||407	      oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID))408		return -EOPNOTSUPP;409 410	if (oct->no_speed_setting) {411		dev_err(&oct->pci_dev->dev, "%s: Changing speed is not supported\n",412			__func__);413		return -EOPNOTSUPP;414	}415 416	if ((ecmd->base.duplex != DUPLEX_UNKNOWN &&417	     ecmd->base.duplex != linfo->link.s.duplex) ||418	     ecmd->base.autoneg != AUTONEG_DISABLE ||419	    (ecmd->base.speed != 10000 && ecmd->base.speed != 25000 &&420	     ecmd->base.speed != SPEED_UNKNOWN))421		return -EOPNOTSUPP;422 423	if ((oct->speed_boot == speed / 1000) &&424	    oct->speed_boot == oct->speed_setting)425		return 0;426 427	liquidio_set_speed(lio, speed / 1000);428 429	dev_dbg(&oct->pci_dev->dev, "Port speed is set to %dG\n",430		oct->speed_setting);431 432	return 0;433}434 435static void436lio_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)437{438	struct lio *lio;439	struct octeon_device *oct;440 441	lio = GET_LIO(netdev);442	oct = lio->oct_dev;443 444	memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));445	strscpy(drvinfo->driver, "liquidio", sizeof(drvinfo->driver));446	strscpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version,447		sizeof(drvinfo->fw_version));448	strscpy(drvinfo->bus_info, pci_name(oct->pci_dev),449		sizeof(drvinfo->bus_info));450}451 452static void453lio_get_vf_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)454{455	struct octeon_device *oct;456	struct lio *lio;457 458	lio = GET_LIO(netdev);459	oct = lio->oct_dev;460 461	memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));462	strscpy(drvinfo->driver, "liquidio_vf", sizeof(drvinfo->driver));463	strscpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version,464		sizeof(drvinfo->fw_version));465	strscpy(drvinfo->bus_info, pci_name(oct->pci_dev),466		sizeof(drvinfo->bus_info));467}468 469static int470lio_send_queue_count_update(struct net_device *netdev, uint32_t num_queues)471{472	struct lio *lio = GET_LIO(netdev);473	struct octeon_device *oct = lio->oct_dev;474	struct octnic_ctrl_pkt nctrl;475	int ret = 0;476 477	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));478 479	nctrl.ncmd.u64 = 0;480	nctrl.ncmd.s.cmd = OCTNET_CMD_QUEUE_COUNT_CTL;481	nctrl.ncmd.s.param1 = num_queues;482	nctrl.ncmd.s.param2 = num_queues;483	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;484	nctrl.netpndev = (u64)netdev;485	nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;486 487	ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);488	if (ret) {489		dev_err(&oct->pci_dev->dev, "Failed to send Queue reset command (ret: 0x%x)\n",490			ret);491		return -1;492	}493 494	return 0;495}496 497static void498lio_ethtool_get_channels(struct net_device *dev,499			 struct ethtool_channels *channel)500{501	struct lio *lio = GET_LIO(dev);502	struct octeon_device *oct = lio->oct_dev;503	u32 max_rx = 0, max_tx = 0, tx_count = 0, rx_count = 0;504	u32 combined_count = 0, max_combined = 0;505 506	if (OCTEON_CN6XXX(oct)) {507		struct octeon_config *conf6x = CHIP_CONF(oct, cn6xxx);508 509		max_rx = CFG_GET_OQ_MAX_Q(conf6x);510		max_tx = CFG_GET_IQ_MAX_Q(conf6x);511		rx_count = CFG_GET_NUM_RXQS_NIC_IF(conf6x, lio->ifidx);512		tx_count = CFG_GET_NUM_TXQS_NIC_IF(conf6x, lio->ifidx);513	} else if (OCTEON_CN23XX_PF(oct)) {514		if (oct->sriov_info.sriov_enabled) {515			max_combined = lio->linfo.num_txpciq;516		} else {517			struct octeon_config *conf23_pf =518				CHIP_CONF(oct, cn23xx_pf);519 520			max_combined = CFG_GET_IQ_MAX_Q(conf23_pf);521		}522		combined_count = oct->num_iqs;523	} else if (OCTEON_CN23XX_VF(oct)) {524		u64 reg_val = 0ULL;525		u64 ctrl = CN23XX_VF_SLI_IQ_PKT_CONTROL64(0);526 527		reg_val = octeon_read_csr64(oct, ctrl);528		reg_val = reg_val >> CN23XX_PKT_INPUT_CTL_RPVF_POS;529		max_combined = reg_val & CN23XX_PKT_INPUT_CTL_RPVF_MASK;530		combined_count = oct->num_iqs;531	}532 533	channel->max_rx = max_rx;534	channel->max_tx = max_tx;535	channel->max_combined = max_combined;536	channel->rx_count = rx_count;537	channel->tx_count = tx_count;538	channel->combined_count = combined_count;539}540 541static int542lio_irq_reallocate_irqs(struct octeon_device *oct, uint32_t num_ioqs)543{544	struct msix_entry *msix_entries;545	int num_msix_irqs = 0;546	int i;547 548	if (!oct->msix_on)549		return 0;550 551	/* Disable the input and output queues now. No more packets will552	 * arrive from Octeon.553	 */554	oct->fn_list.disable_interrupt(oct, OCTEON_ALL_INTR);555 556	if (oct->msix_on) {557		if (OCTEON_CN23XX_PF(oct))558			num_msix_irqs = oct->num_msix_irqs - 1;559		else if (OCTEON_CN23XX_VF(oct))560			num_msix_irqs = oct->num_msix_irqs;561 562		msix_entries = (struct msix_entry *)oct->msix_entries;563		for (i = 0; i < num_msix_irqs; i++) {564			if (oct->ioq_vector[i].vector) {565				/* clear the affinity_cpumask */566				irq_set_affinity_hint(msix_entries[i].vector,567						      NULL);568				free_irq(msix_entries[i].vector,569					 &oct->ioq_vector[i]);570				oct->ioq_vector[i].vector = 0;571			}572		}573 574		/* non-iov vector's argument is oct struct */575		if (OCTEON_CN23XX_PF(oct))576			free_irq(msix_entries[i].vector, oct);577 578		pci_disable_msix(oct->pci_dev);579		kfree(oct->msix_entries);580		oct->msix_entries = NULL;581	}582 583	kfree(oct->irq_name_storage);584	oct->irq_name_storage = NULL;585 586	if (octeon_allocate_ioq_vector(oct, num_ioqs)) {587		dev_err(&oct->pci_dev->dev, "OCTEON: ioq vector allocation failed\n");588		return -1;589	}590 591	if (octeon_setup_interrupt(oct, num_ioqs)) {592		dev_info(&oct->pci_dev->dev, "Setup interrupt failed\n");593		return -1;594	}595 596	/* Enable Octeon device interrupts */597	oct->fn_list.enable_interrupt(oct, OCTEON_ALL_INTR);598 599	return 0;600}601 602static int603lio_ethtool_set_channels(struct net_device *dev,604			 struct ethtool_channels *channel)605{606	u32 combined_count, max_combined;607	struct lio *lio = GET_LIO(dev);608	struct octeon_device *oct = lio->oct_dev;609	int stopped = 0;610 611	if (strcmp(oct->fw_info.liquidio_firmware_version, "1.6.1") < 0) {612		dev_err(&oct->pci_dev->dev, "Minimum firmware version required is 1.6.1\n");613		return -EINVAL;614	}615 616	if (!channel->combined_count || channel->other_count ||617	    channel->rx_count || channel->tx_count)618		return -EINVAL;619 620	combined_count = channel->combined_count;621 622	if (OCTEON_CN23XX_PF(oct)) {623		if (oct->sriov_info.sriov_enabled) {624			max_combined = lio->linfo.num_txpciq;625		} else {626			struct octeon_config *conf23_pf =627				CHIP_CONF(oct,628					  cn23xx_pf);629 630			max_combined =631				CFG_GET_IQ_MAX_Q(conf23_pf);632		}633	} else if (OCTEON_CN23XX_VF(oct)) {634		u64 reg_val = 0ULL;635		u64 ctrl = CN23XX_VF_SLI_IQ_PKT_CONTROL64(0);636 637		reg_val = octeon_read_csr64(oct, ctrl);638		reg_val = reg_val >> CN23XX_PKT_INPUT_CTL_RPVF_POS;639		max_combined = reg_val & CN23XX_PKT_INPUT_CTL_RPVF_MASK;640	} else {641		return -EINVAL;642	}643 644	if (combined_count > max_combined || combined_count < 1)645		return -EINVAL;646 647	if (combined_count == oct->num_iqs)648		return 0;649 650	ifstate_set(lio, LIO_IFSTATE_RESETTING);651 652	if (netif_running(dev)) {653		dev->netdev_ops->ndo_stop(dev);654		stopped = 1;655	}656 657	if (lio_reset_queues(dev, combined_count))658		return -EINVAL;659 660	if (stopped)661		dev->netdev_ops->ndo_open(dev);662 663	ifstate_reset(lio, LIO_IFSTATE_RESETTING);664 665	return 0;666}667 668static int lio_get_eeprom_len(struct net_device *netdev)669{670	u8 buf[192];671	struct lio *lio = GET_LIO(netdev);672	struct octeon_device *oct_dev = lio->oct_dev;673	struct octeon_board_info *board_info;674	int len;675 676	board_info = (struct octeon_board_info *)(&oct_dev->boardinfo);677	len = sprintf(buf, "boardname:%s serialnum:%s maj:%lld min:%lld\n",678		      board_info->name, board_info->serial_number,679		      board_info->major, board_info->minor);680 681	return len;682}683 684static int685lio_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,686	       u8 *bytes)687{688	struct lio *lio = GET_LIO(netdev);689	struct octeon_device *oct_dev = lio->oct_dev;690	struct octeon_board_info *board_info;691 692	if (eeprom->offset)693		return -EINVAL;694 695	eeprom->magic = oct_dev->pci_dev->vendor;696	board_info = (struct octeon_board_info *)(&oct_dev->boardinfo);697	sprintf((char *)bytes,698		"boardname:%s serialnum:%s maj:%lld min:%lld\n",699		board_info->name, board_info->serial_number,700		board_info->major, board_info->minor);701 702	return 0;703}704 705static int octnet_gpio_access(struct net_device *netdev, int addr, int val)706{707	struct lio *lio = GET_LIO(netdev);708	struct octeon_device *oct = lio->oct_dev;709	struct octnic_ctrl_pkt nctrl;710	int ret = 0;711 712	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));713 714	nctrl.ncmd.u64 = 0;715	nctrl.ncmd.s.cmd = OCTNET_CMD_GPIO_ACCESS;716	nctrl.ncmd.s.param1 = addr;717	nctrl.ncmd.s.param2 = val;718	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;719	nctrl.netpndev = (u64)netdev;720	nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;721 722	ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);723	if (ret) {724		dev_err(&oct->pci_dev->dev,725			"Failed to configure gpio value, ret=%d\n", ret);726		return -EINVAL;727	}728 729	return 0;730}731 732static int octnet_id_active(struct net_device *netdev, int val)733{734	struct lio *lio = GET_LIO(netdev);735	struct octeon_device *oct = lio->oct_dev;736	struct octnic_ctrl_pkt nctrl;737	int ret = 0;738 739	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));740 741	nctrl.ncmd.u64 = 0;742	nctrl.ncmd.s.cmd = OCTNET_CMD_ID_ACTIVE;743	nctrl.ncmd.s.param1 = val;744	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;745	nctrl.netpndev = (u64)netdev;746	nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;747 748	ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);749	if (ret) {750		dev_err(&oct->pci_dev->dev,751			"Failed to configure gpio value, ret=%d\n", ret);752		return -EINVAL;753	}754 755	return 0;756}757 758/* This routine provides PHY access routines for759 * mdio  clause45 .760 */761static int762octnet_mdio45_access(struct lio *lio, int op, int loc, int *value)763{764	struct octeon_device *oct_dev = lio->oct_dev;765	struct octeon_soft_command *sc;766	struct oct_mdio_cmd_resp *mdio_cmd_rsp;767	struct oct_mdio_cmd *mdio_cmd;768	int retval = 0;769 770	sc = (struct octeon_soft_command *)771		octeon_alloc_soft_command(oct_dev,772					  sizeof(struct oct_mdio_cmd),773					  sizeof(struct oct_mdio_cmd_resp), 0);774 775	if (!sc)776		return -ENOMEM;777 778	mdio_cmd_rsp = (struct oct_mdio_cmd_resp *)sc->virtrptr;779	mdio_cmd = (struct oct_mdio_cmd *)sc->virtdptr;780 781	mdio_cmd->op = op;782	mdio_cmd->mdio_addr = loc;783	if (op)784		mdio_cmd->value1 = *value;785	octeon_swap_8B_data((u64 *)mdio_cmd, sizeof(struct oct_mdio_cmd) / 8);786 787	sc->iq_no = lio->linfo.txpciq[0].s.q_no;788 789	octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, OPCODE_NIC_MDIO45,790				    0, 0, 0);791 792	init_completion(&sc->complete);793	sc->sc_status = OCTEON_REQUEST_PENDING;794 795	retval = octeon_send_soft_command(oct_dev, sc);796	if (retval == IQ_SEND_FAILED) {797		dev_err(&oct_dev->pci_dev->dev,798			"octnet_mdio45_access instruction failed status: %x\n",799			retval);800		octeon_free_soft_command(oct_dev, sc);801		return -EBUSY;802	} else {803		/* Sleep on a wait queue till the cond flag indicates that the804		 * response arrived805		 */806		retval = wait_for_sc_completion_timeout(oct_dev, sc, 0);807		if (retval)808			return retval;809 810		retval = mdio_cmd_rsp->status;811		if (retval) {812			dev_err(&oct_dev->pci_dev->dev,813				"octnet mdio45 access failed: %x\n", retval);814			WRITE_ONCE(sc->caller_is_done, true);815			return -EBUSY;816		}817 818		octeon_swap_8B_data((u64 *)(&mdio_cmd_rsp->resp),819				    sizeof(struct oct_mdio_cmd) / 8);820 821		if (!op)822			*value = mdio_cmd_rsp->resp.value1;823 824		WRITE_ONCE(sc->caller_is_done, true);825	}826 827	return retval;828}829 830static int lio_set_phys_id(struct net_device *netdev,831			   enum ethtool_phys_id_state state)832{833	struct lio *lio = GET_LIO(netdev);834	struct octeon_device *oct = lio->oct_dev;835	struct oct_link_info *linfo;836	int value, ret;837	u32 cur_ver;838 839	linfo = &lio->linfo;840	cur_ver = OCT_FW_VER(oct->fw_info.ver.maj,841			     oct->fw_info.ver.min,842			     oct->fw_info.ver.rev);843 844	switch (state) {845	case ETHTOOL_ID_ACTIVE:846		if (oct->chip_id == OCTEON_CN66XX) {847			octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,848					   VITESSE_PHY_GPIO_DRIVEON);849			return 2;850 851		} else if (oct->chip_id == OCTEON_CN68XX) {852			/* Save the current LED settings */853			ret = octnet_mdio45_access(lio, 0,854						   LIO68XX_LED_BEACON_ADDR,855						   &lio->phy_beacon_val);856			if (ret)857				return ret;858 859			ret = octnet_mdio45_access(lio, 0,860						   LIO68XX_LED_CTRL_ADDR,861						   &lio->led_ctrl_val);862			if (ret)863				return ret;864 865			/* Configure Beacon values */866			value = LIO68XX_LED_BEACON_CFGON;867			ret = octnet_mdio45_access(lio, 1,868						   LIO68XX_LED_BEACON_ADDR,869						   &value);870			if (ret)871				return ret;872 873			value = LIO68XX_LED_CTRL_CFGON;874			ret = octnet_mdio45_access(lio, 1,875						   LIO68XX_LED_CTRL_ADDR,876						   &value);877			if (ret)878				return ret;879		} else if (oct->chip_id == OCTEON_CN23XX_PF_VID) {880			octnet_id_active(netdev, LED_IDENTIFICATION_ON);881			if (linfo->link.s.phy_type == LIO_PHY_PORT_TP &&882			    cur_ver > OCT_FW_VER(1, 7, 2))883				return 2;884			else885				return 0;886		} else {887			return -EINVAL;888		}889		break;890 891	case ETHTOOL_ID_ON:892		if (oct->chip_id == OCTEON_CN23XX_PF_VID &&893		    linfo->link.s.phy_type == LIO_PHY_PORT_TP &&894		    cur_ver > OCT_FW_VER(1, 7, 2))895			octnet_id_active(netdev, LED_IDENTIFICATION_ON);896		else if (oct->chip_id == OCTEON_CN66XX)897			octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,898					   VITESSE_PHY_GPIO_HIGH);899		else900			return -EINVAL;901 902		break;903 904	case ETHTOOL_ID_OFF:905		if (oct->chip_id == OCTEON_CN23XX_PF_VID &&906		    linfo->link.s.phy_type == LIO_PHY_PORT_TP &&907		    cur_ver > OCT_FW_VER(1, 7, 2))908			octnet_id_active(netdev, LED_IDENTIFICATION_OFF);909		else if (oct->chip_id == OCTEON_CN66XX)910			octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,911					   VITESSE_PHY_GPIO_LOW);912		else913			return -EINVAL;914 915		break;916 917	case ETHTOOL_ID_INACTIVE:918		if (oct->chip_id == OCTEON_CN66XX) {919			octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,920					   VITESSE_PHY_GPIO_DRIVEOFF);921		} else if (oct->chip_id == OCTEON_CN68XX) {922			/* Restore LED settings */923			ret = octnet_mdio45_access(lio, 1,924						   LIO68XX_LED_CTRL_ADDR,925						   &lio->led_ctrl_val);926			if (ret)927				return ret;928 929			ret = octnet_mdio45_access(lio, 1,930						   LIO68XX_LED_BEACON_ADDR,931						   &lio->phy_beacon_val);932			if (ret)933				return ret;934		} else if (oct->chip_id == OCTEON_CN23XX_PF_VID) {935			octnet_id_active(netdev, LED_IDENTIFICATION_OFF);936 937			return 0;938		} else {939			return -EINVAL;940		}941		break;942 943	default:944		return -EINVAL;945	}946 947	return 0;948}949 950static void951lio_ethtool_get_ringparam(struct net_device *netdev,952			  struct ethtool_ringparam *ering,953			  struct kernel_ethtool_ringparam *kernel_ering,954			  struct netlink_ext_ack *extack)955{956	struct lio *lio = GET_LIO(netdev);957	struct octeon_device *oct = lio->oct_dev;958	u32 tx_max_pending = 0, rx_max_pending = 0, tx_pending = 0,959	    rx_pending = 0;960 961	if (ifstate_check(lio, LIO_IFSTATE_RESETTING))962		return;963 964	if (OCTEON_CN6XXX(oct)) {965		struct octeon_config *conf6x = CHIP_CONF(oct, cn6xxx);966 967		tx_max_pending = CN6XXX_MAX_IQ_DESCRIPTORS;968		rx_max_pending = CN6XXX_MAX_OQ_DESCRIPTORS;969		rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf6x, lio->ifidx);970		tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf6x, lio->ifidx);971	} else if (OCTEON_CN23XX_PF(oct) || OCTEON_CN23XX_VF(oct)) {972		tx_max_pending = CN23XX_MAX_IQ_DESCRIPTORS;973		rx_max_pending = CN23XX_MAX_OQ_DESCRIPTORS;974		rx_pending = oct->droq[0]->max_count;975		tx_pending = oct->instr_queue[0]->max_count;976	}977 978	ering->tx_pending = tx_pending;979	ering->tx_max_pending = tx_max_pending;980	ering->rx_pending = rx_pending;981	ering->rx_max_pending = rx_max_pending;982	ering->rx_mini_pending = 0;983	ering->rx_jumbo_pending = 0;984	ering->rx_mini_max_pending = 0;985	ering->rx_jumbo_max_pending = 0;986}987 988static int lio_23xx_reconfigure_queue_count(struct lio *lio)989{990	struct octeon_device *oct = lio->oct_dev;991	u32 resp_size, data_size;992	struct liquidio_if_cfg_resp *resp;993	struct octeon_soft_command *sc;994	union oct_nic_if_cfg if_cfg;995	struct lio_version *vdata;996	u32 ifidx_or_pfnum;997	int retval;998	int j;999 1000	resp_size = sizeof(struct liquidio_if_cfg_resp);1001	data_size = sizeof(struct lio_version);1002	sc = (struct octeon_soft_command *)1003		octeon_alloc_soft_command(oct, data_size,1004					  resp_size, 0);1005	if (!sc) {1006		dev_err(&oct->pci_dev->dev, "%s: Failed to allocate soft command\n",1007			__func__);1008		return -1;1009	}1010 1011	resp = (struct liquidio_if_cfg_resp *)sc->virtrptr;1012	vdata = (struct lio_version *)sc->virtdptr;1013 1014	vdata->major = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MAJOR_VERSION);1015	vdata->minor = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MINOR_VERSION);1016	vdata->micro = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MICRO_VERSION);1017 1018	ifidx_or_pfnum = oct->pf_num;1019 1020	if_cfg.u64 = 0;1021	if_cfg.s.num_iqueues = oct->sriov_info.num_pf_rings;1022	if_cfg.s.num_oqueues = oct->sriov_info.num_pf_rings;1023	if_cfg.s.base_queue = oct->sriov_info.pf_srn;1024	if_cfg.s.gmx_port_id = oct->pf_num;1025 1026	sc->iq_no = 0;1027	octeon_prepare_soft_command(oct, sc, OPCODE_NIC,1028				    OPCODE_NIC_QCOUNT_UPDATE, 0,1029				    if_cfg.u64, 0);1030 1031	init_completion(&sc->complete);1032	sc->sc_status = OCTEON_REQUEST_PENDING;1033 1034	retval = octeon_send_soft_command(oct, sc);1035	if (retval == IQ_SEND_FAILED) {1036		dev_err(&oct->pci_dev->dev,1037			"Sending iq/oq config failed status: %x\n",1038			retval);1039		octeon_free_soft_command(oct, sc);1040		return -EIO;1041	}1042 1043	retval = wait_for_sc_completion_timeout(oct, sc, 0);1044	if (retval)1045		return retval;1046 1047	retval = resp->status;1048	if (retval) {1049		dev_err(&oct->pci_dev->dev,1050			"iq/oq config failed: %x\n", retval);1051		WRITE_ONCE(sc->caller_is_done, true);1052		return -1;1053	}1054 1055	octeon_swap_8B_data((u64 *)(&resp->cfg_info),1056			    (sizeof(struct liquidio_if_cfg_info)) >> 3);1057 1058	lio->ifidx = ifidx_or_pfnum;1059	lio->linfo.num_rxpciq = hweight64(resp->cfg_info.iqmask);1060	lio->linfo.num_txpciq = hweight64(resp->cfg_info.iqmask);1061	for (j = 0; j < lio->linfo.num_rxpciq; j++) {1062		lio->linfo.rxpciq[j].u64 =1063			resp->cfg_info.linfo.rxpciq[j].u64;1064	}1065 1066	for (j = 0; j < lio->linfo.num_txpciq; j++) {1067		lio->linfo.txpciq[j].u64 =1068			resp->cfg_info.linfo.txpciq[j].u64;1069	}1070 1071	lio->linfo.hw_addr = resp->cfg_info.linfo.hw_addr;1072	lio->linfo.gmxport = resp->cfg_info.linfo.gmxport;1073	lio->linfo.link.u64 = resp->cfg_info.linfo.link.u64;1074	lio->txq = lio->linfo.txpciq[0].s.q_no;1075	lio->rxq = lio->linfo.rxpciq[0].s.q_no;1076 1077	dev_info(&oct->pci_dev->dev, "Queue count updated to %d\n",1078		 lio->linfo.num_rxpciq);1079 1080	WRITE_ONCE(sc->caller_is_done, true);1081 1082	return 0;1083}1084 1085static int lio_reset_queues(struct net_device *netdev, uint32_t num_qs)1086{1087	struct lio *lio = GET_LIO(netdev);1088	struct octeon_device *oct = lio->oct_dev;1089	int i, queue_count_update = 0;1090	struct napi_struct *napi, *n;1091	int ret;1092 1093	schedule_timeout_uninterruptible(msecs_to_jiffies(100));1094 1095	if (wait_for_pending_requests(oct))1096		dev_err(&oct->pci_dev->dev, "There were pending requests\n");1097 1098	if (lio_wait_for_instr_fetch(oct))1099		dev_err(&oct->pci_dev->dev, "IQ had pending instructions\n");1100 1101	if (octeon_set_io_queues_off(oct)) {1102		dev_err(&oct->pci_dev->dev, "Setting io queues off failed\n");1103		return -1;1104	}1105 1106	/* Disable the input and output queues now. No more packets will1107	 * arrive from Octeon.1108	 */1109	oct->fn_list.disable_io_queues(oct);1110	/* Delete NAPI */1111	list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list)1112		netif_napi_del(napi);1113 1114	if (num_qs != oct->num_iqs) {1115		ret = netif_set_real_num_rx_queues(netdev, num_qs);1116		if (ret) {1117			dev_err(&oct->pci_dev->dev,1118				"Setting real number rx failed\n");1119			return ret;1120		}1121 1122		ret = netif_set_real_num_tx_queues(netdev, num_qs);1123		if (ret) {1124			dev_err(&oct->pci_dev->dev,1125				"Setting real number tx failed\n");1126			return ret;1127		}1128 1129		/* The value of queue_count_update decides whether it is the1130		 * queue count or the descriptor count that is being1131		 * re-configured.1132		 */1133		queue_count_update = 1;1134	}1135 1136	/* Re-configuration of queues can happen in two scenarios, SRIOV enabled1137	 * and SRIOV disabled. Few things like recreating queue zero, resetting1138	 * glists and IRQs are required for both. For the latter, some more1139	 * steps like updating sriov_info for the octeon device need to be done.1140	 */1141	if (queue_count_update) {1142		cleanup_rx_oom_poll_fn(netdev);1143 1144		lio_delete_glists(lio);1145 1146		/* Delete mbox for PF which is SRIOV disabled because sriov_info1147		 * will be now changed.1148		 */1149		if ((OCTEON_CN23XX_PF(oct)) && !oct->sriov_info.sriov_enabled)1150			oct->fn_list.free_mbox(oct);1151	}1152 1153	for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct); i++) {1154		if (!(oct->io_qmask.oq & BIT_ULL(i)))1155			continue;1156		octeon_delete_droq(oct, i);1157	}1158 1159	for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct); i++) {1160		if (!(oct->io_qmask.iq & BIT_ULL(i)))1161			continue;1162		octeon_delete_instr_queue(oct, i);1163	}1164 1165	if (queue_count_update) {1166		/* For PF re-configure sriov related information */1167		if ((OCTEON_CN23XX_PF(oct)) &&1168		    !oct->sriov_info.sriov_enabled) {1169			oct->sriov_info.num_pf_rings = num_qs;1170			if (cn23xx_sriov_config(oct)) {1171				dev_err(&oct->pci_dev->dev,1172					"Queue reset aborted: SRIOV config failed\n");1173				return -1;1174			}1175 1176			num_qs = oct->sriov_info.num_pf_rings;1177		}1178	}1179 1180	if (oct->fn_list.setup_device_regs(oct)) {1181		dev_err(&oct->pci_dev->dev, "Failed to configure device registers\n");1182		return -1;1183	}1184 1185	/* The following are needed in case of queue count re-configuration and1186	 * not for descriptor count re-configuration.1187	 */1188	if (queue_count_update) {1189		if (octeon_setup_instr_queues(oct))1190			return -1;1191 1192		if (octeon_setup_output_queues(oct))1193			return -1;1194 1195		/* Recreating mbox for PF that is SRIOV disabled */1196		if (OCTEON_CN23XX_PF(oct) && !oct->sriov_info.sriov_enabled) {1197			if (oct->fn_list.setup_mbox(oct)) {1198				dev_err(&oct->pci_dev->dev, "Mailbox setup failed\n");1199				return -1;1200			}1201		}1202 1203		/* Deleting and recreating IRQs whether the interface is SRIOV1204		 * enabled or disabled.1205		 */1206		if (lio_irq_reallocate_irqs(oct, num_qs)) {1207			dev_err(&oct->pci_dev->dev, "IRQs could not be allocated\n");1208			return -1;1209		}1210 1211		/* Enable the input and output queues for this Octeon device */1212		if (oct->fn_list.enable_io_queues(oct)) {1213			dev_err(&oct->pci_dev->dev, "Failed to enable input/output queues\n");1214			return -1;1215		}1216 1217		for (i = 0; i < oct->num_oqs; i++)1218			writel(oct->droq[i]->max_count,1219			       oct->droq[i]->pkts_credit_reg);1220 1221		/* Informing firmware about the new queue count. It is required1222		 * for firmware to allocate more number of queues than those at1223		 * load time.1224		 */1225		if (OCTEON_CN23XX_PF(oct) && !oct->sriov_info.sriov_enabled) {1226			if (lio_23xx_reconfigure_queue_count(lio))1227				return -1;1228		}1229	}1230 1231	/* Once firmware is aware of the new value, queues can be recreated */1232	if (liquidio_setup_io_queues(oct, 0, num_qs, num_qs)) {1233		dev_err(&oct->pci_dev->dev, "I/O queues creation failed\n");1234		return -1;1235	}1236 1237	if (queue_count_update) {1238		if (lio_setup_glists(oct, lio, num_qs)) {1239			dev_err(&oct->pci_dev->dev, "Gather list allocation failed\n");1240			return -1;1241		}1242 1243		if (setup_rx_oom_poll_fn(netdev)) {1244			dev_err(&oct->pci_dev->dev, "lio_setup_rx_oom_poll_fn failed\n");1245			return 1;1246		}1247 1248		/* Send firmware the information about new number of queues1249		 * if the interface is a VF or a PF that is SRIOV enabled.1250		 */1251		if (oct->sriov_info.sriov_enabled || OCTEON_CN23XX_VF(oct))1252			if (lio_send_queue_count_update(netdev, num_qs))1253				return -1;1254	}1255 1256	return 0;1257}1258 1259static int1260lio_ethtool_set_ringparam(struct net_device *netdev,1261			  struct ethtool_ringparam *ering,1262			  struct kernel_ethtool_ringparam *kernel_ering,1263			  struct netlink_ext_ack *extack)1264{1265	u32 rx_count, tx_count, rx_count_old, tx_count_old;1266	struct lio *lio = GET_LIO(netdev);1267	struct octeon_device *oct = lio->oct_dev;1268	int stopped = 0;1269 1270	if (!OCTEON_CN23XX_PF(oct) && !OCTEON_CN23XX_VF(oct))1271		return -EINVAL;1272 1273	if (ering->rx_mini_pending || ering->rx_jumbo_pending)1274		return -EINVAL;1275 1276	rx_count = clamp_t(u32, ering->rx_pending, CN23XX_MIN_OQ_DESCRIPTORS,1277			   CN23XX_MAX_OQ_DESCRIPTORS);1278	tx_count = clamp_t(u32, ering->tx_pending, CN23XX_MIN_IQ_DESCRIPTORS,1279			   CN23XX_MAX_IQ_DESCRIPTORS);1280 1281	rx_count_old = oct->droq[0]->max_count;1282	tx_count_old = oct->instr_queue[0]->max_count;1283 1284	if (rx_count == rx_count_old && tx_count == tx_count_old)1285		return 0;1286 1287	ifstate_set(lio, LIO_IFSTATE_RESETTING);1288 1289	if (netif_running(netdev)) {1290		netdev->netdev_ops->ndo_stop(netdev);1291		stopped = 1;1292	}1293 1294	/* Change RX/TX DESCS  count */1295	if (tx_count != tx_count_old)1296		CFG_SET_NUM_TX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx,1297					    tx_count);1298	if (rx_count != rx_count_old)1299		CFG_SET_NUM_RX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx,1300					    rx_count);1301 1302	if (lio_reset_queues(netdev, oct->num_iqs))1303		goto err_lio_reset_queues;1304 1305	if (stopped)1306		netdev->netdev_ops->ndo_open(netdev);1307 1308	ifstate_reset(lio, LIO_IFSTATE_RESETTING);1309 1310	return 0;1311 1312err_lio_reset_queues:1313	if (tx_count != tx_count_old)1314		CFG_SET_NUM_TX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx,1315					    tx_count_old);1316	if (rx_count != rx_count_old)1317		CFG_SET_NUM_RX_DESCS_NIC_IF(octeon_get_conf(oct), lio->ifidx,1318					    rx_count_old);1319	return -EINVAL;1320}1321 1322static u32 lio_get_msglevel(struct net_device *netdev)1323{1324	struct lio *lio = GET_LIO(netdev);1325 1326	return lio->msg_enable;1327}1328 1329static void lio_set_msglevel(struct net_device *netdev, u32 msglvl)1330{1331	struct lio *lio = GET_LIO(netdev);1332 1333	if ((msglvl ^ lio->msg_enable) & NETIF_MSG_HW) {1334		if (msglvl & NETIF_MSG_HW)1335			liquidio_set_feature(netdev,1336					     OCTNET_CMD_VERBOSE_ENABLE, 0);1337		else1338			liquidio_set_feature(netdev,1339					     OCTNET_CMD_VERBOSE_DISABLE, 0);1340	}1341 1342	lio->msg_enable = msglvl;1343}1344 1345static void lio_vf_set_msglevel(struct net_device *netdev, u32 msglvl)1346{1347	struct lio *lio = GET_LIO(netdev);1348 1349	lio->msg_enable = msglvl;1350}1351 1352static void1353lio_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)1354{1355	/* Notes: Not supporting any auto negotiation in these1356	 * drivers. Just report pause frame support.1357	 */1358	struct lio *lio = GET_LIO(netdev);1359	struct octeon_device *oct = lio->oct_dev;1360 1361	pause->autoneg = 0;1362 1363	pause->tx_pause = oct->tx_pause;1364	pause->rx_pause = oct->rx_pause;1365}1366 1367static int1368lio_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)1369{1370	/* Notes: Not supporting any auto negotiation in these1371	 * drivers.1372	 */1373	struct lio *lio = GET_LIO(netdev);1374	struct octeon_device *oct = lio->oct_dev;1375	struct octnic_ctrl_pkt nctrl;1376	struct oct_link_info *linfo = &lio->linfo;1377 1378	int ret = 0;1379 1380	if (oct->chip_id != OCTEON_CN23XX_PF_VID)1381		return -EINVAL;1382 1383	if (linfo->link.s.duplex == 0) {1384		/*no flow control for half duplex*/1385		if (pause->rx_pause || pause->tx_pause)1386			return -EINVAL;1387	}1388 1389	/*do not support autoneg of link flow control*/1390	if (pause->autoneg == AUTONEG_ENABLE)1391		return -EINVAL;1392 1393	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));1394 1395	nctrl.ncmd.u64 = 0;1396	nctrl.ncmd.s.cmd = OCTNET_CMD_SET_FLOW_CTL;1397	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;1398	nctrl.netpndev = (u64)netdev;1399	nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;1400 1401	if (pause->rx_pause) {1402		/*enable rx pause*/1403		nctrl.ncmd.s.param1 = 1;1404	} else {1405		/*disable rx pause*/1406		nctrl.ncmd.s.param1 = 0;1407	}1408 1409	if (pause->tx_pause) {1410		/*enable tx pause*/1411		nctrl.ncmd.s.param2 = 1;1412	} else {1413		/*disable tx pause*/1414		nctrl.ncmd.s.param2 = 0;1415	}1416 1417	ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);1418	if (ret) {1419		dev_err(&oct->pci_dev->dev,1420			"Failed to set pause parameter, ret=%d\n", ret);1421		return -EINVAL;1422	}1423 1424	oct->rx_pause = pause->rx_pause;1425	oct->tx_pause = pause->tx_pause;1426 1427	return 0;1428}1429 1430static void1431lio_get_ethtool_stats(struct net_device *netdev,1432		      struct ethtool_stats *stats  __attribute__((unused)),1433		      u64 *data)1434{1435	struct lio *lio = GET_LIO(netdev);1436	struct octeon_device *oct_dev = lio->oct_dev;1437	struct rtnl_link_stats64 lstats;1438	int i = 0, j;1439 1440	if (ifstate_check(lio, LIO_IFSTATE_RESETTING))1441		return;1442 1443	netdev->netdev_ops->ndo_get_stats64(netdev, &lstats);1444	/*sum of oct->droq[oq_no]->stats->rx_pkts_received */1445	data[i++] = lstats.rx_packets;1446	/*sum of oct->instr_queue[iq_no]->stats.tx_done */1447	data[i++] = lstats.tx_packets;1448	/*sum of oct->droq[oq_no]->stats->rx_bytes_received */1449	data[i++] = lstats.rx_bytes;1450	/*sum of oct->instr_queue[iq_no]->stats.tx_tot_bytes */1451	data[i++] = lstats.tx_bytes;1452	data[i++] = lstats.rx_errors +1453			oct_dev->link_stats.fromwire.fcs_err +1454			oct_dev->link_stats.fromwire.jabber_err +1455			oct_dev->link_stats.fromwire.l2_err +1456			oct_dev->link_stats.fromwire.frame_err;1457	data[i++] = lstats.tx_errors;1458	/*sum of oct->droq[oq_no]->stats->rx_dropped +1459	 *oct->droq[oq_no]->stats->dropped_nodispatch +1460	 *oct->droq[oq_no]->stats->dropped_toomany +1461	 *oct->droq[oq_no]->stats->dropped_nomem1462	 */1463	data[i++] = lstats.rx_dropped +1464			oct_dev->link_stats.fromwire.fifo_err +1465			oct_dev->link_stats.fromwire.dmac_drop +1466			oct_dev->link_stats.fromwire.red_drops +1467			oct_dev->link_stats.fromwire.fw_err_pko +1468			oct_dev->link_stats.fromwire.fw_err_link +1469			oct_dev->link_stats.fromwire.fw_err_drop;1470	/*sum of oct->instr_queue[iq_no]->stats.tx_dropped */1471	data[i++] = lstats.tx_dropped +1472			oct_dev->link_stats.fromhost.max_collision_fail +1473			oct_dev->link_stats.fromhost.max_deferral_fail +1474			oct_dev->link_stats.fromhost.total_collisions +1475			oct_dev->link_stats.fromhost.fw_err_pko +1476			oct_dev->link_stats.fromhost.fw_err_link +1477			oct_dev->link_stats.fromhost.fw_err_drop +1478			oct_dev->link_stats.fromhost.fw_err_pki;1479 1480	/* firmware tx stats */1481	/*per_core_stats[cvmx_get_core_num()].link_stats[mdata->from_ifidx].1482	 *fromhost.fw_total_sent1483	 */1484	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_total_sent);1485	/*per_core_stats[i].link_stats[port].fromwire.fw_total_fwd */1486	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_total_fwd);1487	/*per_core_stats[j].link_stats[i].fromhost.fw_err_pko */1488	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_pko);1489	/*per_core_stats[j].link_stats[i].fromhost.fw_err_pki */1490	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_pki);1491	/*per_core_stats[j].link_stats[i].fromhost.fw_err_link */1492	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_link);1493	/*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.1494	 *fw_err_drop1495	 */1496	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_drop);1497 1498	/*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.fw_tso */1499	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tso);1500	/*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.1501	 *fw_tso_fwd1502	 */1503	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tso_fwd);1504	/*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.1505	 *fw_err_tso1506	 */1507	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_tso);1508	/*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.1509	 *fw_tx_vxlan1510	 */1511	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tx_vxlan);1512 1513	/* Multicast packets sent by this port */1514	data[i++] = oct_dev->link_stats.fromhost.fw_total_mcast_sent;1515	data[i++] = oct_dev->link_stats.fromhost.fw_total_bcast_sent;1516 1517	/* mac tx statistics */1518	/*CVMX_BGXX_CMRX_TX_STAT5 */1519	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_pkts_sent);1520	/*CVMX_BGXX_CMRX_TX_STAT4 */1521	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_bytes_sent);1522	/*CVMX_BGXX_CMRX_TX_STAT15 */1523	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.mcast_pkts_sent);1524	/*CVMX_BGXX_CMRX_TX_STAT14 */1525	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.bcast_pkts_sent);1526	/*CVMX_BGXX_CMRX_TX_STAT17 */1527	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.ctl_sent);1528	/*CVMX_BGXX_CMRX_TX_STAT0 */1529	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_collisions);1530	/*CVMX_BGXX_CMRX_TX_STAT3 */1531	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.one_collision_sent);1532	/*CVMX_BGXX_CMRX_TX_STAT2 */1533	data[i++] =1534		CVM_CAST64(oct_dev->link_stats.fromhost.multi_collision_sent);1535	/*CVMX_BGXX_CMRX_TX_STAT0 */1536	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.max_collision_fail);1537	/*CVMX_BGXX_CMRX_TX_STAT1 */1538	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.max_deferral_fail);1539	/*CVMX_BGXX_CMRX_TX_STAT16 */1540	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fifo_err);1541	/*CVMX_BGXX_CMRX_TX_STAT6 */1542	data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.runts);1543 1544	/* RX firmware stats */1545	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.1546	 *fw_total_rcvd1547	 */1548	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_rcvd);1549	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.1550	 *fw_total_fwd1551	 */1552	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_fwd);1553	/* Multicast packets received on this port */1554	data[i++] = oct_dev->link_stats.fromwire.fw_total_mcast;1555	data[i++] = oct_dev->link_stats.fromwire.fw_total_bcast;1556	/*per_core_stats[core_id].link_stats[ifidx].fromwire.jabber_err */1557	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.jabber_err);1558	/*per_core_stats[core_id].link_stats[ifidx].fromwire.l2_err */1559	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.l2_err);1560	/*per_core_stats[core_id].link_stats[ifidx].fromwire.frame_err */1561	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.frame_err);1562	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.1563	 *fw_err_pko1564	 */1565	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_pko);1566	/*per_core_stats[j].link_stats[i].fromwire.fw_err_link */1567	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_link);1568	/*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx].1569	 *fromwire.fw_err_drop1570	 */1571	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_drop);1572 1573	/*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx].1574	 *fromwire.fw_rx_vxlan1575	 */1576	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_rx_vxlan);1577	/*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx].1578	 *fromwire.fw_rx_vxlan_err1579	 */1580	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_rx_vxlan_err);1581 1582	/* LRO */1583	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.1584	 *fw_lro_pkts1585	 */1586	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_pkts);1587	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.1588	 *fw_lro_octs1589	 */1590	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_octs);1591	/*per_core_stats[j].link_stats[i].fromwire.fw_total_lro */1592	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_lro);1593	/*per_core_stats[j].link_stats[i].fromwire.fw_lro_aborts */1594	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts);1595	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.1596	 *fw_lro_aborts_port1597	 */1598	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_port);1599	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.1600	 *fw_lro_aborts_seq1601	 */1602	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_seq);1603	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.1604	 *fw_lro_aborts_tsval1605	 */1606	data[i++] =1607		CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_tsval);1608	/*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.1609	 *fw_lro_aborts_timer1610	 */1611	/* intrmod: packet forward rate */1612	data[i++] =1613		CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_timer);1614	/*per_core_stats[j].link_stats[i].fromwire.fw_lro_aborts */1615	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fwd_rate);1616 1617	/* mac: link-level stats */1618	/*CVMX_BGXX_CMRX_RX_STAT0 */1619	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_rcvd);1620	/*CVMX_BGXX_CMRX_RX_STAT1 */1621	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.bytes_rcvd);1622	/*CVMX_PKI_STATX_STAT5 */1623	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_bcst);1624	/*CVMX_PKI_STATX_STAT5 */1625	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_mcst);1626	/*wqe->word2.err_code or wqe->word2.err_level */1627	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.runts);1628	/*CVMX_BGXX_CMRX_RX_STAT2 */1629	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.ctl_rcvd);1630	/*CVMX_BGXX_CMRX_RX_STAT6 */1631	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fifo_err);1632	/*CVMX_BGXX_CMRX_RX_STAT4 */1633	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.dmac_drop);1634	/*wqe->word2.err_code or wqe->word2.err_level */1635	data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fcs_err);1636	/*lio->link_changes*/1637	data[i++] = CVM_CAST64(lio->link_changes);1638 1639	for (j = 0; j < MAX_OCTEON_INSTR_QUEUES(oct_dev); j++) {1640		if (!(oct_dev->io_qmask.iq & BIT_ULL(j)))1641			continue;1642		/*packets to network port*/1643		/*# of packets tx to network */1644		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_done);1645		/*# of bytes tx to network */1646		data[i++] =1647			CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_tot_bytes);1648		/*# of packets dropped */1649		data[i++] =1650			CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_dropped);1651		/*# of tx fails due to queue full */1652		data[i++] =1653			CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_iq_busy);1654		/*XXX gather entries sent */1655		data[i++] =1656			CVM_CAST64(oct_dev->instr_queue[j]->stats.sgentry_sent);1657 1658		/*instruction to firmware: data and control */1659		/*# of instructions to the queue */1660		data[i++] =1661			CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_posted);1662		/*# of instructions processed */1663		data[i++] = CVM_CAST64(1664				oct_dev->instr_queue[j]->stats.instr_processed);1665		/*# of instructions could not be processed */1666		data[i++] = CVM_CAST64(1667				oct_dev->instr_queue[j]->stats.instr_dropped);1668		/*bytes sent through the queue */1669		data[i++] =1670			CVM_CAST64(oct_dev->instr_queue[j]->stats.bytes_sent);1671 1672		/*tso request*/1673		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_gso);1674		/*vxlan request*/1675		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_vxlan);1676		/*txq restart*/1677		data[i++] =1678			CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_restart);1679	}1680 1681	/* RX */1682	for (j = 0; j < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); j++) {1683		if (!(oct_dev->io_qmask.oq & BIT_ULL(j)))1684			continue;1685 1686		/*packets send to TCP/IP network stack */1687		/*# of packets to network stack */1688		data[i++] =1689			CVM_CAST64(oct_dev->droq[j]->stats.rx_pkts_received);1690		/*# of bytes to network stack */1691		data[i++] =1692			CVM_CAST64(oct_dev->droq[j]->stats.rx_bytes_received);1693		/*# of packets dropped */1694		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem +1695				       oct_dev->droq[j]->stats.dropped_toomany +1696				       oct_dev->droq[j]->stats.rx_dropped);1697		data[i++] =1698			CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem);1699		data[i++] =1700			CVM_CAST64(oct_dev->droq[j]->stats.dropped_toomany);1701		data[i++] =1702			CVM_CAST64(oct_dev->droq[j]->stats.rx_dropped);1703 1704		/*control and data path*/1705		data[i++] =1706			CVM_CAST64(oct_dev->droq[j]->stats.pkts_received);1707		data[i++] =1708			CVM_CAST64(oct_dev->droq[j]->stats.bytes_received);1709		data[i++] =1710			CVM_CAST64(oct_dev->droq[j]->stats.dropped_nodispatch);1711 1712		data[i++] =1713			CVM_CAST64(oct_dev->droq[j]->stats.rx_vxlan);1714		data[i++] =1715			CVM_CAST64(oct_dev->droq[j]->stats.rx_alloc_failure);1716	}1717}1718 1719static void lio_vf_get_ethtool_stats(struct net_device *netdev,1720				     struct ethtool_stats *stats1721				     __attribute__((unused)),1722				     u64 *data)1723{1724	struct rtnl_link_stats64 lstats;1725	struct lio *lio = GET_LIO(netdev);1726	struct octeon_device *oct_dev = lio->oct_dev;1727	int i = 0, j, vj;1728 1729	if (ifstate_check(lio, LIO_IFSTATE_RESETTING))1730		return;1731 1732	netdev->netdev_ops->ndo_get_stats64(netdev, &lstats);1733	/* sum of oct->droq[oq_no]->stats->rx_pkts_received */1734	data[i++] = lstats.rx_packets;1735	/* sum of oct->instr_queue[iq_no]->stats.tx_done */1736	data[i++] = lstats.tx_packets;1737	/* sum of oct->droq[oq_no]->stats->rx_bytes_received */1738	data[i++] = lstats.rx_bytes;1739	/* sum of oct->instr_queue[iq_no]->stats.tx_tot_bytes */1740	data[i++] = lstats.tx_bytes;1741	data[i++] = lstats.rx_errors;1742	data[i++] = lstats.tx_errors;1743	 /* sum of oct->droq[oq_no]->stats->rx_dropped +1744	  * oct->droq[oq_no]->stats->dropped_nodispatch +1745	  * oct->droq[oq_no]->stats->dropped_toomany +1746	  * oct->droq[oq_no]->stats->dropped_nomem1747	  */1748	data[i++] = lstats.rx_dropped;1749	/* sum of oct->instr_queue[iq_no]->stats.tx_dropped */1750	data[i++] = lstats.tx_dropped +1751		oct_dev->link_stats.fromhost.fw_err_drop;1752 1753	data[i++] = oct_dev->link_stats.fromwire.fw_total_mcast;1754	data[i++] = oct_dev->link_stats.fromhost.fw_total_mcast_sent;1755	data[i++] = oct_dev->link_stats.fromwire.fw_total_bcast;1756	data[i++] = oct_dev->link_stats.fromhost.fw_total_bcast_sent;1757 1758	/* lio->link_changes */1759	data[i++] = CVM_CAST64(lio->link_changes);1760 1761	for (vj = 0; vj < oct_dev->num_iqs; vj++) {1762		j = lio->linfo.txpciq[vj].s.q_no;1763 1764		/* packets to network port */1765		/* # of packets tx to network */1766		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_done);1767		 /* # of bytes tx to network */1768		data[i++] = CVM_CAST64(1769				oct_dev->instr_queue[j]->stats.tx_tot_bytes);1770		/* # of packets dropped */1771		data[i++] = CVM_CAST64(1772				oct_dev->instr_queue[j]->stats.tx_dropped);1773		/* # of tx fails due to queue full */1774		data[i++] = CVM_CAST64(1775				oct_dev->instr_queue[j]->stats.tx_iq_busy);1776		/* XXX gather entries sent */1777		data[i++] = CVM_CAST64(1778				oct_dev->instr_queue[j]->stats.sgentry_sent);1779 1780		/* instruction to firmware: data and control */1781		/* # of instructions to the queue */1782		data[i++] = CVM_CAST64(1783				oct_dev->instr_queue[j]->stats.instr_posted);1784		/* # of instructions processed */1785		data[i++] =1786		    CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_processed);1787		/* # of instructions could not be processed */1788		data[i++] =1789		    CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_dropped);1790		/* bytes sent through the queue */1791		data[i++] = CVM_CAST64(1792				oct_dev->instr_queue[j]->stats.bytes_sent);1793		/* tso request */1794		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_gso);1795		/* vxlan request */1796		data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_vxlan);1797		/* txq restart */1798		data[i++] = CVM_CAST64(1799				oct_dev->instr_queue[j]->stats.tx_restart);1800	}1801 1802	/* RX */1803	for (vj = 0; vj < oct_dev->num_oqs; vj++) {1804		j = lio->linfo.rxpciq[vj].s.q_no;1805 1806		/* packets send to TCP/IP network stack */1807		/* # of packets to network stack */1808		data[i++] = CVM_CAST64(1809				oct_dev->droq[j]->stats.rx_pkts_received);1810		/* # of bytes to network stack */1811		data[i++] = CVM_CAST64(1812				oct_dev->droq[j]->stats.rx_bytes_received);1813		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem +1814				       oct_dev->droq[j]->stats.dropped_toomany +1815				       oct_dev->droq[j]->stats.rx_dropped);1816		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem);1817		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_toomany);1818		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.rx_dropped);1819 1820		/* control and data path */1821		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.pkts_received);1822		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.bytes_received);1823		data[i++] =1824			CVM_CAST64(oct_dev->droq[j]->stats.dropped_nodispatch);1825 1826		data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.rx_vxlan);1827		data[i++] =1828		    CVM_CAST64(oct_dev->droq[j]->stats.rx_alloc_failure);1829	}1830}1831 1832static void lio_get_priv_flags_strings(struct lio *lio, u8 *data)1833{1834	struct octeon_device *oct_dev = lio->oct_dev;1835	int i;1836 1837	switch (oct_dev->chip_id) {1838	case OCTEON_CN23XX_PF_VID:1839	case OCTEON_CN23XX_VF_VID:1840		for (i = 0; i < ARRAY_SIZE(oct_priv_flags_strings); i++) {1841			sprintf(data, "%s", oct_priv_flags_strings[i]);1842			data += ETH_GSTRING_LEN;1843		}1844		break;1845	case OCTEON_CN68XX:1846	case OCTEON_CN66XX:1847		break;1848	default:1849		netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n");1850		break;1851	}1852}1853 1854static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data)1855{1856	struct lio *lio = GET_LIO(netdev);1857	struct octeon_device *oct_dev = lio->oct_dev;1858	int num_iq_stats, num_oq_stats, i, j;1859	int num_stats;1860 1861	switch (stringset) {1862	case ETH_SS_STATS:1863		num_stats = ARRAY_SIZE(oct_stats_strings);1864		for (j = 0; j < num_stats; j++) {1865			sprintf(data, "%s", oct_stats_strings[j]);1866			data += ETH_GSTRING_LEN;1867		}1868 1869		num_iq_stats = ARRAY_SIZE(oct_iq_stats_strings);1870		for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct_dev); i++) {1871			if (!(oct_dev->io_qmask.iq & BIT_ULL(i)))1872				continue;1873			for (j = 0; j < num_iq_stats; j++) {1874				sprintf(data, "tx-%d-%s", i,1875					oct_iq_stats_strings[j]);1876				data += ETH_GSTRING_LEN;1877			}1878		}1879 1880		num_oq_stats = ARRAY_SIZE(oct_droq_stats_strings);1881		for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); i++) {1882			if (!(oct_dev->io_qmask.oq & BIT_ULL(i)))1883				continue;1884			for (j = 0; j < num_oq_stats; j++) {1885				sprintf(data, "rx-%d-%s", i,1886					oct_droq_stats_strings[j]);1887				data += ETH_GSTRING_LEN;1888			}1889		}1890		break;1891 1892	case ETH_SS_PRIV_FLAGS:1893		lio_get_priv_flags_strings(lio, data);1894		break;1895	default:1896		netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n");1897		break;1898	}1899}1900 1901static void lio_vf_get_strings(struct net_device *netdev, u32 stringset,1902			       u8 *data)1903{1904	int num_iq_stats, num_oq_stats, i, j;1905	struct lio *lio = GET_LIO(netdev);1906	struct octeon_device *oct_dev = lio->oct_dev;1907	int num_stats;1908 1909	switch (stringset) {1910	case ETH_SS_STATS:1911		num_stats = ARRAY_SIZE(oct_vf_stats_strings);1912		for (j = 0; j < num_stats; j++) {1913			sprintf(data, "%s", oct_vf_stats_strings[j]);1914			data += ETH_GSTRING_LEN;1915		}1916 1917		num_iq_stats = ARRAY_SIZE(oct_iq_stats_strings);1918		for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct_dev); i++) {1919			if (!(oct_dev->io_qmask.iq & BIT_ULL(i)))1920				continue;1921			for (j = 0; j < num_iq_stats; j++) {1922				sprintf(data, "tx-%d-%s", i,1923					oct_iq_stats_strings[j]);1924				data += ETH_GSTRING_LEN;1925			}1926		}1927 1928		num_oq_stats = ARRAY_SIZE(oct_droq_stats_strings);1929		for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); i++) {1930			if (!(oct_dev->io_qmask.oq & BIT_ULL(i)))1931				continue;1932			for (j = 0; j < num_oq_stats; j++) {1933				sprintf(data, "rx-%d-%s", i,1934					oct_droq_stats_strings[j]);1935				data += ETH_GSTRING_LEN;1936			}1937		}1938		break;1939 1940	case ETH_SS_PRIV_FLAGS:1941		lio_get_priv_flags_strings(lio, data);1942		break;1943	default:1944		netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n");1945		break;1946	}1947}1948 1949static int lio_get_priv_flags_ss_count(struct lio *lio)1950{1951	struct octeon_device *oct_dev = lio->oct_dev;1952 1953	switch (oct_dev->chip_id) {1954	case OCTEON_CN23XX_PF_VID:1955	case OCTEON_CN23XX_VF_VID:1956		return ARRAY_SIZE(oct_priv_flags_strings);1957	case OCTEON_CN68XX:1958	case OCTEON_CN66XX:1959		return -EOPNOTSUPP;1960	default:1961		netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n");1962		return -EOPNOTSUPP;1963	}1964}1965 1966static int lio_get_sset_count(struct net_device *netdev, int sset)1967{1968	struct lio *lio = GET_LIO(netdev);1969	struct octeon_device *oct_dev = lio->oct_dev;1970 1971	switch (sset) {1972	case ETH_SS_STATS:1973		return (ARRAY_SIZE(oct_stats_strings) +1974			ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs +1975			ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs);1976	case ETH_SS_PRIV_FLAGS:1977		return lio_get_priv_flags_ss_count(lio);1978	default:1979		return -EOPNOTSUPP;1980	}1981}1982 1983static int lio_vf_get_sset_count(struct net_device *netdev, int sset)1984{1985	struct lio *lio = GET_LIO(netdev);1986	struct octeon_device *oct_dev = lio->oct_dev;1987 1988	switch (sset) {1989	case ETH_SS_STATS:1990		return (ARRAY_SIZE(oct_vf_stats_strings) +1991			ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs +1992			ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs);1993	case ETH_SS_PRIV_FLAGS:1994		return lio_get_priv_flags_ss_count(lio);1995	default:1996		return -EOPNOTSUPP;1997	}1998}1999 2000/*  get interrupt moderation parameters */2001static int octnet_get_intrmod_cfg(struct lio *lio,2002				  struct oct_intrmod_cfg *intr_cfg)2003{2004	struct octeon_soft_command *sc;2005	struct oct_intrmod_resp *resp;2006	int retval;2007	struct octeon_device *oct_dev = lio->oct_dev;2008 2009	/* Alloc soft command */2010	sc = (struct octeon_soft_command *)2011		octeon_alloc_soft_command(oct_dev,2012					  0,2013					  sizeof(struct oct_intrmod_resp), 0);2014 2015	if (!sc)2016		return -ENOMEM;2017 2018	resp = (struct oct_intrmod_resp *)sc->virtrptr;2019	memset(resp, 0, sizeof(struct oct_intrmod_resp));2020 2021	sc->iq_no = lio->linfo.txpciq[0].s.q_no;2022 2023	octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC,2024				    OPCODE_NIC_INTRMOD_PARAMS, 0, 0, 0);2025 2026	init_completion(&sc->complete);2027	sc->sc_status = OCTEON_REQUEST_PENDING;2028 2029	retval = octeon_send_soft_command(oct_dev, sc);2030	if (retval == IQ_SEND_FAILED) {2031		octeon_free_soft_command(oct_dev, sc);2032		return -EINVAL;2033	}2034 2035	/* Sleep on a wait queue till the cond flag indicates that the2036	 * response arrived or timed-out.2037	 */2038	retval = wait_for_sc_completion_timeout(oct_dev, sc, 0);2039	if (retval)2040		return -ENODEV;2041 2042	if (resp->status) {2043		dev_err(&oct_dev->pci_dev->dev,2044			"Get interrupt moderation parameters failed\n");2045		WRITE_ONCE(sc->caller_is_done, true);2046		return -ENODEV;2047	}2048 2049	octeon_swap_8B_data((u64 *)&resp->intrmod,2050			    (sizeof(struct oct_intrmod_cfg)) / 8);2051	memcpy(intr_cfg, &resp->intrmod, sizeof(struct oct_intrmod_cfg));2052	WRITE_ONCE(sc->caller_is_done, true);2053 2054	return 0;2055}2056 2057/*  Configure interrupt moderation parameters */2058static int octnet_set_intrmod_cfg(struct lio *lio,2059				  struct oct_intrmod_cfg *intr_cfg)2060{2061	struct octeon_soft_command *sc;2062	struct oct_intrmod_cfg *cfg;2063	int retval;2064	struct octeon_device *oct_dev = lio->oct_dev;2065 2066	/* Alloc soft command */2067	sc = (struct octeon_soft_command *)2068		octeon_alloc_soft_command(oct_dev,2069					  sizeof(struct oct_intrmod_cfg),2070					  16, 0);2071 2072	if (!sc)2073		return -ENOMEM;2074 2075	cfg = (struct oct_intrmod_cfg *)sc->virtdptr;2076 2077	memcpy(cfg, intr_cfg, sizeof(struct oct_intrmod_cfg));2078	octeon_swap_8B_data((u64 *)cfg, (sizeof(struct oct_intrmod_cfg)) / 8);2079 2080	sc->iq_no = lio->linfo.txpciq[0].s.q_no;2081 2082	octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC,2083				    OPCODE_NIC_INTRMOD_CFG, 0, 0, 0);2084 2085	init_completion(&sc->complete);2086	sc->sc_status = OCTEON_REQUEST_PENDING;2087 2088	retval = octeon_send_soft_command(oct_dev, sc);2089	if (retval == IQ_SEND_FAILED) {2090		octeon_free_soft_command(oct_dev, sc);2091		return -EINVAL;2092	}2093 2094	/* Sleep on a wait queue till the cond flag indicates that the2095	 * response arrived or timed-out.2096	 */2097	retval = wait_for_sc_completion_timeout(oct_dev, sc, 0);2098	if (retval)2099		return retval;2100 2101	retval = sc->sc_status;2102	if (retval == 0) {2103		dev_info(&oct_dev->pci_dev->dev,2104			 "Rx-Adaptive Interrupt moderation %s\n",2105			 (intr_cfg->rx_enable) ?2106			 "enabled" : "disabled");2107		WRITE_ONCE(sc->caller_is_done, true);2108		return 0;2109	}2110 2111	dev_err(&oct_dev->pci_dev->dev,2112		"intrmod config failed. Status: %x\n", retval);2113	WRITE_ONCE(sc->caller_is_done, true);2114	return -ENODEV;2115}2116 2117static int lio_get_intr_coalesce(struct net_device *netdev,2118				 struct ethtool_coalesce *intr_coal,2119				 struct kernel_ethtool_coalesce *kernel_coal,2120				 struct netlink_ext_ack *extack)2121{2122	struct lio *lio = GET_LIO(netdev);2123	struct octeon_device *oct = lio->oct_dev;2124	struct octeon_instr_queue *iq;2125	struct oct_intrmod_cfg intrmod_cfg;2126 2127	if (octnet_get_intrmod_cfg(lio, &intrmod_cfg))2128		return -ENODEV;2129 2130	switch (oct->chip_id) {2131	case OCTEON_CN23XX_PF_VID:2132	case OCTEON_CN23XX_VF_VID: {2133		if (!intrmod_cfg.rx_enable) {2134			intr_coal->rx_coalesce_usecs = oct->rx_coalesce_usecs;2135			intr_coal->rx_max_coalesced_frames =2136				oct->rx_max_coalesced_frames;2137		}2138		if (!intrmod_cfg.tx_enable)2139			intr_coal->tx_max_coalesced_frames =2140				oct->tx_max_coalesced_frames;2141		break;2142	}2143	case OCTEON_CN68XX:2144	case OCTEON_CN66XX: {2145		struct octeon_cn6xxx *cn6xxx =2146			(struct octeon_cn6xxx *)oct->chip;2147 2148		if (!intrmod_cfg.rx_enable) {2149			intr_coal->rx_coalesce_usecs =2150				CFG_GET_OQ_INTR_TIME(cn6xxx->conf);2151			intr_coal->rx_max_coalesced_frames =2152				CFG_GET_OQ_INTR_PKT(cn6xxx->conf);2153		}2154		iq = oct->instr_queue[lio->linfo.txpciq[0].s.q_no];2155		intr_coal->tx_max_coalesced_frames = iq->fill_threshold;2156		break;2157	}2158	default:2159		netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n");2160		return -EINVAL;2161	}2162	if (intrmod_cfg.rx_enable) {2163		intr_coal->use_adaptive_rx_coalesce =2164			intrmod_cfg.rx_enable;2165		intr_coal->rate_sample_interval =2166			intrmod_cfg.check_intrvl;2167		intr_coal->pkt_rate_high =2168			intrmod_cfg.maxpkt_ratethr;2169		intr_coal->pkt_rate_low =2170			intrmod_cfg.minpkt_ratethr;2171		intr_coal->rx_max_coalesced_frames_high =2172			intrmod_cfg.rx_maxcnt_trigger;2173		intr_coal->rx_coalesce_usecs_high =2174			intrmod_cfg.rx_maxtmr_trigger;2175		intr_coal->rx_coalesce_usecs_low =2176			intrmod_cfg.rx_mintmr_trigger;2177		intr_coal->rx_max_coalesced_frames_low =2178			intrmod_cfg.rx_mincnt_trigger;2179	}2180	if ((OCTEON_CN23XX_PF(oct) || OCTEON_CN23XX_VF(oct)) &&2181	    (intrmod_cfg.tx_enable)) {2182		intr_coal->use_adaptive_tx_coalesce =2183			intrmod_cfg.tx_enable;2184		intr_coal->tx_max_coalesced_frames_high =2185			intrmod_cfg.tx_maxcnt_trigger;2186		intr_coal->tx_max_coalesced_frames_low =2187			intrmod_cfg.tx_mincnt_trigger;2188	}2189	return 0;2190}2191 2192/* Enable/Disable auto interrupt Moderation */2193static int oct_cfg_adaptive_intr(struct lio *lio,2194				 struct oct_intrmod_cfg *intrmod_cfg,2195				 struct ethtool_coalesce *intr_coal)2196{2197	int ret = 0;2198 2199	if (intrmod_cfg->rx_enable || intrmod_cfg->tx_enable) {2200		intrmod_cfg->check_intrvl = intr_coal->rate_sample_interval;2201		intrmod_cfg->maxpkt_ratethr = intr_coal->pkt_rate_high;2202		intrmod_cfg->minpkt_ratethr = intr_coal->pkt_rate_low;2203	}2204	if (intrmod_cfg->rx_enable) {2205		intrmod_cfg->rx_maxcnt_trigger =2206			intr_coal->rx_max_coalesced_frames_high;2207		intrmod_cfg->rx_maxtmr_trigger =2208			intr_coal->rx_coalesce_usecs_high;2209		intrmod_cfg->rx_mintmr_trigger =2210			intr_coal->rx_coalesce_usecs_low;2211		intrmod_cfg->rx_mincnt_trigger =2212			intr_coal->rx_max_coalesced_frames_low;2213	}2214	if (intrmod_cfg->tx_enable) {2215		intrmod_cfg->tx_maxcnt_trigger =2216			intr_coal->tx_max_coalesced_frames_high;2217		intrmod_cfg->tx_mincnt_trigger =2218			intr_coal->tx_max_coalesced_frames_low;2219	}2220 2221	ret = octnet_set_intrmod_cfg(lio, intrmod_cfg);2222 2223	return ret;2224}2225 2226static int2227oct_cfg_rx_intrcnt(struct lio *lio,2228		   struct oct_intrmod_cfg *intrmod,2229		   struct ethtool_coalesce *intr_coal)2230{2231	struct octeon_device *oct = lio->oct_dev;2232	u32 rx_max_coalesced_frames;2233 2234	/* Config Cnt based interrupt values */2235	switch (oct->chip_id) {2236	case OCTEON_CN68XX:2237	case OCTEON_CN66XX: {2238		struct octeon_cn6xxx *cn6xxx =2239			(struct octeon_cn6xxx *)oct->chip;2240 2241		if (!intr_coal->rx_max_coalesced_frames)2242			rx_max_coalesced_frames = CN6XXX_OQ_INTR_PKT;2243		else2244			rx_max_coalesced_frames =2245				intr_coal->rx_max_coalesced_frames;2246		octeon_write_csr(oct, CN6XXX_SLI_OQ_INT_LEVEL_PKTS,2247				 rx_max_coalesced_frames);2248		CFG_SET_OQ_INTR_PKT(cn6xxx->conf, rx_max_coalesced_frames);2249		break;2250	}2251	case OCTEON_CN23XX_PF_VID: {2252		int q_no;2253 2254		if (!intr_coal->rx_max_coalesced_frames)2255			rx_max_coalesced_frames = intrmod->rx_frames;2256		else2257			rx_max_coalesced_frames =2258			    intr_coal->rx_max_coalesced_frames;2259		for (q_no = 0; q_no < oct->num_oqs; q_no++) {2260			q_no += oct->sriov_info.pf_srn;2261			octeon_write_csr64(2262			    oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no),2263			    (octeon_read_csr64(2264				 oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no)) &2265			     (0x3fffff00000000UL)) |2266				(rx_max_coalesced_frames - 1));2267			/*consider setting resend bit*/2268		}2269		intrmod->rx_frames = rx_max_coalesced_frames;2270		oct->rx_max_coalesced_frames = rx_max_coalesced_frames;2271		break;2272	}2273	case OCTEON_CN23XX_VF_VID: {2274		int q_no;2275 2276		if (!intr_coal->rx_max_coalesced_frames)2277			rx_max_coalesced_frames = intrmod->rx_frames;2278		else2279			rx_max_coalesced_frames =2280			    intr_coal->rx_max_coalesced_frames;2281		for (q_no = 0; q_no < oct->num_oqs; q_no++) {2282			octeon_write_csr64(2283			    oct, CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(q_no),2284			    (octeon_read_csr64(2285				 oct, CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(q_no)) &2286			     (0x3fffff00000000UL)) |2287				(rx_max_coalesced_frames - 1));2288			/*consider writing to resend bit here*/2289		}2290		intrmod->rx_frames = rx_max_coalesced_frames;2291		oct->rx_max_coalesced_frames = rx_max_coalesced_frames;2292		break;2293	}2294	default:2295		return -EINVAL;2296	}2297	return 0;2298}2299 2300static int oct_cfg_rx_intrtime(struct lio *lio,2301			       struct oct_intrmod_cfg *intrmod,2302			       struct ethtool_coalesce *intr_coal)2303{2304	struct octeon_device *oct = lio->oct_dev;2305	u32 time_threshold, rx_coalesce_usecs;2306 2307	/* Config Time based interrupt values */2308	switch (oct->chip_id) {2309	case OCTEON_CN68XX:2310	case OCTEON_CN66XX: {2311		struct octeon_cn6xxx *cn6xxx =2312			(struct octeon_cn6xxx *)oct->chip;2313		if (!intr_coal->rx_coalesce_usecs)2314			rx_coalesce_usecs = CN6XXX_OQ_INTR_TIME;2315		else2316			rx_coalesce_usecs = intr_coal->rx_coalesce_usecs;2317 2318		time_threshold = lio_cn6xxx_get_oq_ticks(oct,2319							 rx_coalesce_usecs);2320		octeon_write_csr(oct,2321				 CN6XXX_SLI_OQ_INT_LEVEL_TIME,2322				 time_threshold);2323 2324		CFG_SET_OQ_INTR_TIME(cn6xxx->conf, rx_coalesce_usecs);2325		break;2326	}2327	case OCTEON_CN23XX_PF_VID: {2328		u64 time_threshold;2329		int q_no;2330 2331		if (!intr_coal->rx_coalesce_usecs)2332			rx_coalesce_usecs = intrmod->rx_usecs;2333		else2334			rx_coalesce_usecs = intr_coal->rx_coalesce_usecs;2335		time_threshold =2336		    cn23xx_pf_get_oq_ticks(oct, (u32)rx_coalesce_usecs);2337		for (q_no = 0; q_no < oct->num_oqs; q_no++) {2338			q_no += oct->sriov_info.pf_srn;2339			octeon_write_csr64(oct,2340					   CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no),2341					   (intrmod->rx_frames |2342					    ((u64)time_threshold << 32)));2343			/*consider writing to resend bit here*/2344		}2345		intrmod->rx_usecs = rx_coalesce_usecs;2346		oct->rx_coalesce_usecs = rx_coalesce_usecs;2347		break;2348	}2349	case OCTEON_CN23XX_VF_VID: {2350		u64 time_threshold;2351		int q_no;2352 2353		if (!intr_coal->rx_coalesce_usecs)2354			rx_coalesce_usecs = intrmod->rx_usecs;2355		else2356			rx_coalesce_usecs = intr_coal->rx_coalesce_usecs;2357 2358		time_threshold =2359		    cn23xx_vf_get_oq_ticks(oct, (u32)rx_coalesce_usecs);2360		for (q_no = 0; q_no < oct->num_oqs; q_no++) {2361			octeon_write_csr64(2362				oct, CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(q_no),2363				(intrmod->rx_frames |2364				 ((u64)time_threshold << 32)));2365			/*consider setting resend bit*/2366		}2367		intrmod->rx_usecs = rx_coalesce_usecs;2368		oct->rx_coalesce_usecs = rx_coalesce_usecs;2369		break;2370	}2371	default:2372		return -EINVAL;2373	}2374 2375	return 0;2376}2377 2378static int2379oct_cfg_tx_intrcnt(struct lio *lio,2380		   struct oct_intrmod_cfg *intrmod,2381		   struct ethtool_coalesce *intr_coal)2382{2383	struct octeon_device *oct = lio->oct_dev;2384	u32 iq_intr_pkt;2385	void __iomem *inst_cnt_reg;2386	u64 val;2387 2388	/* Config Cnt based interrupt values */2389	switch (oct->chip_id) {2390	case OCTEON_CN68XX:2391	case OCTEON_CN66XX:2392		break;2393	case OCTEON_CN23XX_VF_VID:2394	case OCTEON_CN23XX_PF_VID: {2395		int q_no;2396 2397		if (!intr_coal->tx_max_coalesced_frames)2398			iq_intr_pkt = CN23XX_DEF_IQ_INTR_THRESHOLD &2399				      CN23XX_PKT_IN_DONE_WMARK_MASK;2400		else2401			iq_intr_pkt = intr_coal->tx_max_coalesced_frames &2402				      CN23XX_PKT_IN_DONE_WMARK_MASK;2403		for (q_no = 0; q_no < oct->num_iqs; q_no++) {2404			inst_cnt_reg = (oct->instr_queue[q_no])->inst_cnt_reg;2405			val = readq(inst_cnt_reg);2406			/*clear wmark and count.dont want to write count back*/2407			val = (val & 0xFFFF000000000000ULL) |2408			      ((u64)(iq_intr_pkt - 1)2409			       << CN23XX_PKT_IN_DONE_WMARK_BIT_POS);2410			writeq(val, inst_cnt_reg);2411			/*consider setting resend bit*/2412		}2413		intrmod->tx_frames = iq_intr_pkt;2414		oct->tx_max_coalesced_frames = iq_intr_pkt;2415		break;2416	}2417	default:2418		return -EINVAL;2419	}2420	return 0;2421}2422 2423static int lio_set_intr_coalesce(struct net_device *netdev,2424				 struct ethtool_coalesce *intr_coal,2425				 struct kernel_ethtool_coalesce *kernel_coal,2426				 struct netlink_ext_ack *extack)2427{2428	struct lio *lio = GET_LIO(netdev);2429	int ret;2430	struct octeon_device *oct = lio->oct_dev;2431	struct oct_intrmod_cfg intrmod = {0};2432	u32 j, q_no;2433	int db_max, db_min;2434 2435	switch (oct->chip_id) {2436	case OCTEON_CN68XX:2437	case OCTEON_CN66XX:2438		db_min = CN6XXX_DB_MIN;2439		db_max = CN6XXX_DB_MAX;2440		if ((intr_coal->tx_max_coalesced_frames >= db_min) &&2441		    (intr_coal->tx_max_coalesced_frames <= db_max)) {2442			for (j = 0; j < lio->linfo.num_txpciq; j++) {2443				q_no = lio->linfo.txpciq[j].s.q_no;2444				oct->instr_queue[q_no]->fill_threshold =2445					intr_coal->tx_max_coalesced_frames;2446			}2447		} else {2448			dev_err(&oct->pci_dev->dev,2449				"LIQUIDIO: Invalid tx-frames:%d. Range is min:%d max:%d\n",2450				intr_coal->tx_max_coalesced_frames,2451				db_min, db_max);2452			return -EINVAL;2453		}2454		break;2455	case OCTEON_CN23XX_PF_VID:2456	case OCTEON_CN23XX_VF_VID:2457		break;2458	default:2459		return -EINVAL;2460	}2461 2462	intrmod.rx_enable = intr_coal->use_adaptive_rx_coalesce ? 1 : 0;2463	intrmod.tx_enable = intr_coal->use_adaptive_tx_coalesce ? 1 : 0;2464	intrmod.rx_frames = CFG_GET_OQ_INTR_PKT(octeon_get_conf(oct));2465	intrmod.rx_usecs = CFG_GET_OQ_INTR_TIME(octeon_get_conf(oct));2466	intrmod.tx_frames = CFG_GET_IQ_INTR_PKT(octeon_get_conf(oct));2467 2468	ret = oct_cfg_adaptive_intr(lio, &intrmod, intr_coal);2469 2470	if (!intr_coal->use_adaptive_rx_coalesce) {2471		ret = oct_cfg_rx_intrtime(lio, &intrmod, intr_coal);2472		if (ret)2473			goto ret_intrmod;2474 2475		ret = oct_cfg_rx_intrcnt(lio, &intrmod, intr_coal);2476		if (ret)2477			goto ret_intrmod;2478	} else {2479		oct->rx_coalesce_usecs =2480			CFG_GET_OQ_INTR_TIME(octeon_get_conf(oct));2481		oct->rx_max_coalesced_frames =2482			CFG_GET_OQ_INTR_PKT(octeon_get_conf(oct));2483	}2484 2485	if (!intr_coal->use_adaptive_tx_coalesce) {2486		ret = oct_cfg_tx_intrcnt(lio, &intrmod, intr_coal);2487		if (ret)2488			goto ret_intrmod;2489	} else {2490		oct->tx_max_coalesced_frames =2491			CFG_GET_IQ_INTR_PKT(octeon_get_conf(oct));2492	}2493 2494	return 0;2495ret_intrmod:2496	return ret;2497}2498 2499#ifdef PTP_HARDWARE_TIMESTAMPING2500static int lio_get_ts_info(struct net_device *netdev,2501			   struct kernel_ethtool_ts_info *info)2502{2503	struct lio *lio = GET_LIO(netdev);2504 2505	info->so_timestamping =2506		SOF_TIMESTAMPING_TX_HARDWARE |2507		SOF_TIMESTAMPING_RX_HARDWARE |2508		SOF_TIMESTAMPING_RAW_HARDWARE |2509		SOF_TIMESTAMPING_TX_SOFTWARE;2510 2511	if (lio->ptp_clock)2512		info->phc_index = ptp_clock_index(lio->ptp_clock);2513 2514	info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);2515 2516	info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |2517			   (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |2518			   (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |2519			   (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT);2520 2521	return 0;2522}2523#endif2524 2525/* Return register dump len. */2526static int lio_get_regs_len(struct net_device *dev)2527{2528	struct lio *lio = GET_LIO(dev);2529	struct octeon_device *oct = lio->oct_dev;2530 2531	switch (oct->chip_id) {2532	case OCTEON_CN23XX_PF_VID:2533		return OCT_ETHTOOL_REGDUMP_LEN_23XX;2534	case OCTEON_CN23XX_VF_VID:2535		return OCT_ETHTOOL_REGDUMP_LEN_23XX_VF;2536	default:2537		return OCT_ETHTOOL_REGDUMP_LEN;2538	}2539}2540 2541static int cn23xx_read_csr_reg(char *s, struct octeon_device *oct)2542{2543	u32 reg;2544	u8 pf_num = oct->pf_num;2545	int len = 0;2546	int i;2547 2548	/* PCI  Window Registers */2549 2550	len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n");2551 2552	/*0x29030 or 0x29040*/2553	reg = CN23XX_SLI_PKT_MAC_RINFO64(oct->pcie_port, oct->pf_num);2554	len += sprintf(s + len,2555		       "\n[%08x] (SLI_PKT_MAC%d_PF%d_RINFO): %016llx\n",2556		       reg, oct->pcie_port, oct->pf_num,2557		       (u64)octeon_read_csr64(oct, reg));2558 2559	/*0x27080 or 0x27090*/2560	reg = CN23XX_SLI_MAC_PF_INT_ENB64(oct->pcie_port, oct->pf_num);2561	len +=2562	    sprintf(s + len, "\n[%08x] (SLI_MAC%d_PF%d_INT_ENB): %016llx\n",2563		    reg, oct->pcie_port, oct->pf_num,2564		    (u64)octeon_read_csr64(oct, reg));2565 2566	/*0x27000 or 0x27010*/2567	reg = CN23XX_SLI_MAC_PF_INT_SUM64(oct->pcie_port, oct->pf_num);2568	len +=2569	    sprintf(s + len, "\n[%08x] (SLI_MAC%d_PF%d_INT_SUM): %016llx\n",2570		    reg, oct->pcie_port, oct->pf_num,2571		    (u64)octeon_read_csr64(oct, reg));2572 2573	/*0x29120*/2574	reg = 0x29120;2575	len += sprintf(s + len, "\n[%08x] (SLI_PKT_MEM_CTL): %016llx\n", reg,2576		       (u64)octeon_read_csr64(oct, reg));2577 2578	/*0x27300*/2579	reg = 0x27300 + oct->pcie_port * CN23XX_MAC_INT_OFFSET +2580	      (oct->pf_num) * CN23XX_PF_INT_OFFSET;2581	len += sprintf(2582	    s + len, "\n[%08x] (SLI_MAC%d_PF%d_PKT_VF_INT): %016llx\n", reg,2583	    oct->pcie_port, oct->pf_num, (u64)octeon_read_csr64(oct, reg));2584 2585	/*0x27200*/2586	reg = 0x27200 + oct->pcie_port * CN23XX_MAC_INT_OFFSET +2587	      (oct->pf_num) * CN23XX_PF_INT_OFFSET;2588	len += sprintf(s + len,2589		       "\n[%08x] (SLI_MAC%d_PF%d_PP_VF_INT): %016llx\n",2590		       reg, oct->pcie_port, oct->pf_num,2591		       (u64)octeon_read_csr64(oct, reg));2592 2593	/*29130*/2594	reg = CN23XX_SLI_PKT_CNT_INT;2595	len += sprintf(s + len, "\n[%08x] (SLI_PKT_CNT_INT): %016llx\n", reg,2596		       (u64)octeon_read_csr64(oct, reg));2597 2598	/*0x29140*/2599	reg = CN23XX_SLI_PKT_TIME_INT;2600	len += sprintf(s + len, "\n[%08x] (SLI_PKT_TIME_INT): %016llx\n", reg,2601		       (u64)octeon_read_csr64(oct, reg));2602 2603	/*0x29160*/2604	reg = 0x29160;2605	len += sprintf(s + len, "\n[%08x] (SLI_PKT_INT): %016llx\n", reg,2606		       (u64)octeon_read_csr64(oct, reg));2607 2608	/*0x29180*/2609	reg = CN23XX_SLI_OQ_WMARK;2610	len += sprintf(s + len, "\n[%08x] (SLI_PKT_OUTPUT_WMARK): %016llx\n",2611		       reg, (u64)octeon_read_csr64(oct, reg));2612 2613	/*0x291E0*/2614	reg = CN23XX_SLI_PKT_IOQ_RING_RST;2615	len += sprintf(s + len, "\n[%08x] (SLI_PKT_RING_RST): %016llx\n", reg,2616		       (u64)octeon_read_csr64(oct, reg));2617 2618	/*0x29210*/2619	reg = CN23XX_SLI_GBL_CONTROL;2620	len += sprintf(s + len,2621		       "\n[%08x] (SLI_PKT_GBL_CONTROL): %016llx\n", reg,2622		       (u64)octeon_read_csr64(oct, reg));2623 2624	/*0x29220*/2625	reg = 0x29220;2626	len += sprintf(s + len, "\n[%08x] (SLI_PKT_BIST_STATUS): %016llx\n",2627		       reg, (u64)octeon_read_csr64(oct, reg));2628 2629	/*PF only*/2630	if (pf_num == 0) {2631		/*0x29260*/2632		reg = CN23XX_SLI_OUT_BP_EN_W1S;2633		len += sprintf(s + len,2634			       "\n[%08x] (SLI_PKT_OUT_BP_EN_W1S):  %016llx\n",2635			       reg, (u64)octeon_read_csr64(oct, reg));2636	} else if (pf_num == 1) {2637		/*0x29270*/2638		reg = CN23XX_SLI_OUT_BP_EN2_W1S;2639		len += sprintf(s + len,2640			       "\n[%08x] (SLI_PKT_OUT_BP_EN2_W1S): %016llx\n",2641			       reg, (u64)octeon_read_csr64(oct, reg));2642	}2643 2644	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {2645		reg = CN23XX_SLI_OQ_BUFF_INFO_SIZE(i);2646		len +=2647		    sprintf(s + len, "\n[%08x] (SLI_PKT%d_OUT_SIZE): %016llx\n",2648			    reg, i, (u64)octeon_read_csr64(oct, reg));2649	}2650 2651	/*0x10040*/2652	for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {2653		reg = CN23XX_SLI_IQ_INSTR_COUNT64(i);2654		len += sprintf(s + len,2655			       "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",2656			       reg, i, (u64)octeon_read_csr64(oct, reg));2657	}2658 2659	/*0x10080*/2660	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {2661		reg = CN23XX_SLI_OQ_PKTS_CREDIT(i);2662		len += sprintf(s + len,2663			       "\n[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016llx\n",2664			       reg, i, (u64)octeon_read_csr64(oct, reg));2665	}2666 2667	/*0x10090*/2668	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {2669		reg = CN23XX_SLI_OQ_SIZE(i);2670		len += sprintf(2671		    s + len, "\n[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016llx\n",2672		    reg, i, (u64)octeon_read_csr64(oct, reg));2673	}2674 2675	/*0x10050*/2676	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {2677		reg = CN23XX_SLI_OQ_PKT_CONTROL(i);2678		len += sprintf(2679			s + len,2680			"\n[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016llx\n",2681			reg, i, (u64)octeon_read_csr64(oct, reg));2682	}2683 2684	/*0x10070*/2685	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {2686		reg = CN23XX_SLI_OQ_BASE_ADDR64(i);2687		len += sprintf(s + len,2688			       "\n[%08x] (SLI_PKT%d_SLIST_BADDR): %016llx\n",2689			       reg, i, (u64)octeon_read_csr64(oct, reg));2690	}2691 2692	/*0x100a0*/2693	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {2694		reg = CN23XX_SLI_OQ_PKT_INT_LEVELS(i);2695		len += sprintf(s + len,2696			       "\n[%08x] (SLI_PKT%d_INT_LEVELS): %016llx\n",2697			       reg, i, (u64)octeon_read_csr64(oct, reg));2698	}2699 2700	/*0x100b0*/2701	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {2702		reg = CN23XX_SLI_OQ_PKTS_SENT(i);2703		len += sprintf(s + len, "\n[%08x] (SLI_PKT%d_CNTS): %016llx\n",2704			       reg, i, (u64)octeon_read_csr64(oct, reg));2705	}2706 2707	/*0x100c0*/2708	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {2709		reg = 0x100c0 + i * CN23XX_OQ_OFFSET;2710		len += sprintf(s + len,2711			       "\n[%08x] (SLI_PKT%d_ERROR_INFO): %016llx\n",2712			       reg, i, (u64)octeon_read_csr64(oct, reg));2713 2714		/*0x10000*/2715		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {2716			reg = CN23XX_SLI_IQ_PKT_CONTROL64(i);2717			len += sprintf(2718				s + len,2719				"\n[%08x] (SLI_PKT%d_INPUT_CONTROL): %016llx\n",2720				reg, i, (u64)octeon_read_csr64(oct, reg));2721		}2722 2723		/*0x10010*/2724		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {2725			reg = CN23XX_SLI_IQ_BASE_ADDR64(i);2726			len += sprintf(2727			    s + len,2728			    "\n[%08x] (SLI_PKT%d_INSTR_BADDR): %016llx\n", reg,2729			    i, (u64)octeon_read_csr64(oct, reg));2730		}2731 2732		/*0x10020*/2733		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {2734			reg = CN23XX_SLI_IQ_DOORBELL(i);2735			len += sprintf(2736			    s + len,2737			    "\n[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016llx\n",2738			    reg, i, (u64)octeon_read_csr64(oct, reg));2739		}2740 2741		/*0x10030*/2742		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {2743			reg = CN23XX_SLI_IQ_SIZE(i);2744			len += sprintf(2745			    s + len,2746			    "\n[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016llx\n",2747			    reg, i, (u64)octeon_read_csr64(oct, reg));2748		}2749 2750		/*0x10040*/2751		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++)2752			reg = CN23XX_SLI_IQ_INSTR_COUNT64(i);2753		len += sprintf(s + len,2754			       "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",2755			       reg, i, (u64)octeon_read_csr64(oct, reg));2756	}2757 2758	return len;2759}2760 2761static int cn23xx_vf_read_csr_reg(char *s, struct octeon_device *oct)2762{2763	int len = 0;2764	u32 reg;2765	int i;2766 2767	/* PCI  Window Registers */2768 2769	len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n");2770 2771	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2772		reg = CN23XX_VF_SLI_OQ_BUFF_INFO_SIZE(i);2773		len += sprintf(s + len,2774			       "\n[%08x] (SLI_PKT%d_OUT_SIZE): %016llx\n",2775			       reg, i, (u64)octeon_read_csr64(oct, reg));2776	}2777 2778	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2779		reg = CN23XX_VF_SLI_IQ_INSTR_COUNT64(i);2780		len += sprintf(s + len,2781			       "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",2782			       reg, i, (u64)octeon_read_csr64(oct, reg));2783	}2784 2785	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2786		reg = CN23XX_VF_SLI_OQ_PKTS_CREDIT(i);2787		len += sprintf(s + len,2788			       "\n[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016llx\n",2789			       reg, i, (u64)octeon_read_csr64(oct, reg));2790	}2791 2792	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2793		reg = CN23XX_VF_SLI_OQ_SIZE(i);2794		len += sprintf(s + len,2795			       "\n[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016llx\n",2796			       reg, i, (u64)octeon_read_csr64(oct, reg));2797	}2798 2799	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2800		reg = CN23XX_VF_SLI_OQ_PKT_CONTROL(i);2801		len += sprintf(s + len,2802			       "\n[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016llx\n",2803			       reg, i, (u64)octeon_read_csr64(oct, reg));2804	}2805 2806	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2807		reg = CN23XX_VF_SLI_OQ_BASE_ADDR64(i);2808		len += sprintf(s + len,2809			       "\n[%08x] (SLI_PKT%d_SLIST_BADDR): %016llx\n",2810			       reg, i, (u64)octeon_read_csr64(oct, reg));2811	}2812 2813	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2814		reg = CN23XX_VF_SLI_OQ_PKT_INT_LEVELS(i);2815		len += sprintf(s + len,2816			       "\n[%08x] (SLI_PKT%d_INT_LEVELS): %016llx\n",2817			       reg, i, (u64)octeon_read_csr64(oct, reg));2818	}2819 2820	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2821		reg = CN23XX_VF_SLI_OQ_PKTS_SENT(i);2822		len += sprintf(s + len, "\n[%08x] (SLI_PKT%d_CNTS): %016llx\n",2823			       reg, i, (u64)octeon_read_csr64(oct, reg));2824	}2825 2826	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2827		reg = 0x100c0 + i * CN23XX_VF_OQ_OFFSET;2828		len += sprintf(s + len,2829			       "\n[%08x] (SLI_PKT%d_ERROR_INFO): %016llx\n",2830			       reg, i, (u64)octeon_read_csr64(oct, reg));2831	}2832 2833	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2834		reg = 0x100d0 + i * CN23XX_VF_IQ_OFFSET;2835		len += sprintf(s + len,2836			       "\n[%08x] (SLI_PKT%d_VF_INT_SUM): %016llx\n",2837			       reg, i, (u64)octeon_read_csr64(oct, reg));2838	}2839 2840	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2841		reg = CN23XX_VF_SLI_IQ_PKT_CONTROL64(i);2842		len += sprintf(s + len,2843			       "\n[%08x] (SLI_PKT%d_INPUT_CONTROL): %016llx\n",2844			       reg, i, (u64)octeon_read_csr64(oct, reg));2845	}2846 2847	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2848		reg = CN23XX_VF_SLI_IQ_BASE_ADDR64(i);2849		len += sprintf(s + len,2850			       "\n[%08x] (SLI_PKT%d_INSTR_BADDR): %016llx\n",2851			       reg, i, (u64)octeon_read_csr64(oct, reg));2852	}2853 2854	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2855		reg = CN23XX_VF_SLI_IQ_DOORBELL(i);2856		len += sprintf(s + len,2857			       "\n[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016llx\n",2858			       reg, i, (u64)octeon_read_csr64(oct, reg));2859	}2860 2861	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2862		reg = CN23XX_VF_SLI_IQ_SIZE(i);2863		len += sprintf(s + len,2864			       "\n[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016llx\n",2865			       reg, i, (u64)octeon_read_csr64(oct, reg));2866	}2867 2868	for (i = 0; i < (oct->sriov_info.rings_per_vf); i++) {2869		reg = CN23XX_VF_SLI_IQ_INSTR_COUNT64(i);2870		len += sprintf(s + len,2871			       "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",2872			       reg, i, (u64)octeon_read_csr64(oct, reg));2873	}2874 2875	return len;2876}2877 2878static int cn6xxx_read_csr_reg(char *s, struct octeon_device *oct)2879{2880	u32 reg;2881	int i, len = 0;2882 2883	/* PCI  Window Registers */2884 2885	len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n");2886	reg = CN6XXX_WIN_WR_ADDR_LO;2887	len += sprintf(s + len, "\n[%02x] (WIN_WR_ADDR_LO): %08x\n",2888		       CN6XXX_WIN_WR_ADDR_LO, octeon_read_csr(oct, reg));2889	reg = CN6XXX_WIN_WR_ADDR_HI;2890	len += sprintf(s + len, "[%02x] (WIN_WR_ADDR_HI): %08x\n",2891		       CN6XXX_WIN_WR_ADDR_HI, octeon_read_csr(oct, reg));2892	reg = CN6XXX_WIN_RD_ADDR_LO;2893	len += sprintf(s + len, "[%02x] (WIN_RD_ADDR_LO): %08x\n",2894		       CN6XXX_WIN_RD_ADDR_LO, octeon_read_csr(oct, reg));2895	reg = CN6XXX_WIN_RD_ADDR_HI;2896	len += sprintf(s + len, "[%02x] (WIN_RD_ADDR_HI): %08x\n",2897		       CN6XXX_WIN_RD_ADDR_HI, octeon_read_csr(oct, reg));2898	reg = CN6XXX_WIN_WR_DATA_LO;2899	len += sprintf(s + len, "[%02x] (WIN_WR_DATA_LO): %08x\n",2900		       CN6XXX_WIN_WR_DATA_LO, octeon_read_csr(oct, reg));2901	reg = CN6XXX_WIN_WR_DATA_HI;2902	len += sprintf(s + len, "[%02x] (WIN_WR_DATA_HI): %08x\n",2903		       CN6XXX_WIN_WR_DATA_HI, octeon_read_csr(oct, reg));2904	len += sprintf(s + len, "[%02x] (WIN_WR_MASK_REG): %08x\n",2905		       CN6XXX_WIN_WR_MASK_REG,2906		       octeon_read_csr(oct, CN6XXX_WIN_WR_MASK_REG));2907 2908	/* PCI  Interrupt Register */2909	len += sprintf(s + len, "\n[%x] (INT_ENABLE PORT 0): %08x\n",2910		       CN6XXX_SLI_INT_ENB64_PORT0, octeon_read_csr(oct,2911						CN6XXX_SLI_INT_ENB64_PORT0));2912	len += sprintf(s + len, "\n[%x] (INT_ENABLE PORT 1): %08x\n",2913		       CN6XXX_SLI_INT_ENB64_PORT1,2914		       octeon_read_csr(oct, CN6XXX_SLI_INT_ENB64_PORT1));2915	len += sprintf(s + len, "[%x] (INT_SUM): %08x\n", CN6XXX_SLI_INT_SUM64,2916		       octeon_read_csr(oct, CN6XXX_SLI_INT_SUM64));2917 2918	/* PCI  Output queue registers */2919	for (i = 0; i < oct->num_oqs; i++) {2920		reg = CN6XXX_SLI_OQ_PKTS_SENT(i);2921		len += sprintf(s + len, "\n[%x] (PKTS_SENT_%d): %08x\n",2922			       reg, i, octeon_read_csr(oct, reg));2923		reg = CN6XXX_SLI_OQ_PKTS_CREDIT(i);2924		len += sprintf(s + len, "[%x] (PKT_CREDITS_%d): %08x\n",2925			       reg, i, octeon_read_csr(oct, reg));2926	}2927	reg = CN6XXX_SLI_OQ_INT_LEVEL_PKTS;2928	len += sprintf(s + len, "\n[%x] (PKTS_SENT_INT_LEVEL): %08x\n",2929		       reg, octeon_read_csr(oct, reg));2930	reg = CN6XXX_SLI_OQ_INT_LEVEL_TIME;2931	len += sprintf(s + len, "[%x] (PKTS_SENT_TIME): %08x\n",2932		       reg, octeon_read_csr(oct, reg));2933 2934	/* PCI  Input queue registers */2935	for (i = 0; i <= 3; i++) {2936		u32 reg;2937 2938		reg = CN6XXX_SLI_IQ_DOORBELL(i);2939		len += sprintf(s + len, "\n[%x] (INSTR_DOORBELL_%d): %08x\n",2940			       reg, i, octeon_read_csr(oct, reg));2941		reg = CN6XXX_SLI_IQ_INSTR_COUNT(i);2942		len += sprintf(s + len, "[%x] (INSTR_COUNT_%d): %08x\n",2943			       reg, i, octeon_read_csr(oct, reg));2944	}2945 2946	/* PCI  DMA registers */2947 2948	len += sprintf(s + len, "\n[%x] (DMA_CNT_0): %08x\n",2949		       CN6XXX_DMA_CNT(0),2950		       octeon_read_csr(oct, CN6XXX_DMA_CNT(0)));2951	reg = CN6XXX_DMA_PKT_INT_LEVEL(0);2952	len += sprintf(s + len, "[%x] (DMA_INT_LEV_0): %08x\n",2953		       CN6XXX_DMA_PKT_INT_LEVEL(0), octeon_read_csr(oct, reg));2954	reg = CN6XXX_DMA_TIME_INT_LEVEL(0);2955	len += sprintf(s + len, "[%x] (DMA_TIME_0): %08x\n",2956		       CN6XXX_DMA_TIME_INT_LEVEL(0),2957		       octeon_read_csr(oct, reg));2958 2959	len += sprintf(s + len, "\n[%x] (DMA_CNT_1): %08x\n",2960		       CN6XXX_DMA_CNT(1),2961		       octeon_read_csr(oct, CN6XXX_DMA_CNT(1)));2962	reg = CN6XXX_DMA_PKT_INT_LEVEL(1);2963	len += sprintf(s + len, "[%x] (DMA_INT_LEV_1): %08x\n",2964		       CN6XXX_DMA_PKT_INT_LEVEL(1),2965		       octeon_read_csr(oct, reg));2966	reg = CN6XXX_DMA_PKT_INT_LEVEL(1);2967	len += sprintf(s + len, "[%x] (DMA_TIME_1): %08x\n",2968		       CN6XXX_DMA_TIME_INT_LEVEL(1),2969		       octeon_read_csr(oct, reg));2970 2971	/* PCI  Index registers */2972 2973	len += sprintf(s + len, "\n");2974 2975	for (i = 0; i < 16; i++) {2976		reg = lio_pci_readq(oct, CN6XXX_BAR1_REG(i, oct->pcie_port));2977		len += sprintf(s + len, "[%llx] (BAR1_INDEX_%02d): %08x\n",2978			       CN6XXX_BAR1_REG(i, oct->pcie_port), i, reg);2979	}2980 2981	return len;2982}2983 2984static int cn6xxx_read_config_reg(char *s, struct octeon_device *oct)2985{2986	u32 val;2987	int i, len = 0;2988 2989	/* PCI CONFIG Registers */2990 2991	len += sprintf(s + len,2992		       "\n\t Octeon Config space Registers\n\n");2993 2994	for (i = 0; i <= 13; i++) {2995		pci_read_config_dword(oct->pci_dev, (i * 4), &val);2996		len += sprintf(s + len, "[0x%x] (Config[%d]): 0x%08x\n",2997			       (i * 4), i, val);2998	}2999 3000	for (i = 30; i <= 34; i++) {3001		pci_read_config_dword(oct->pci_dev, (i * 4), &val);3002		len += sprintf(s + len, "[0x%x] (Config[%d]): 0x%08x\n",3003			       (i * 4), i, val);3004	}3005 3006	return len;3007}3008 3009/*  Return register dump user app.  */3010static void lio_get_regs(struct net_device *dev,3011			 struct ethtool_regs *regs, void *regbuf)3012{3013	struct lio *lio = GET_LIO(dev);3014	int len = 0;3015	struct octeon_device *oct = lio->oct_dev;3016 3017	regs->version = OCT_ETHTOOL_REGSVER;3018 3019	switch (oct->chip_id) {3020	case OCTEON_CN23XX_PF_VID:3021		memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN_23XX);3022		len += cn23xx_read_csr_reg(regbuf + len, oct);3023		break;3024	case OCTEON_CN23XX_VF_VID:3025		memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN_23XX_VF);3026		len += cn23xx_vf_read_csr_reg(regbuf + len, oct);3027		break;3028	case OCTEON_CN68XX:3029	case OCTEON_CN66XX:3030		memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN);3031		len += cn6xxx_read_csr_reg(regbuf + len, oct);3032		len += cn6xxx_read_config_reg(regbuf + len, oct);3033		break;3034	default:3035		dev_err(&oct->pci_dev->dev, "%s Unknown chipid: %d\n",3036			__func__, oct->chip_id);3037	}3038}3039 3040static u32 lio_get_priv_flags(struct net_device *netdev)3041{3042	struct lio *lio = GET_LIO(netdev);3043 3044	return lio->oct_dev->priv_flags;3045}3046 3047static int lio_set_priv_flags(struct net_device *netdev, u32 flags)3048{3049	struct lio *lio = GET_LIO(netdev);3050	bool intr_by_tx_bytes = !!(flags & (0x1 << OCT_PRIV_FLAG_TX_BYTES));3051 3052	lio_set_priv_flag(lio->oct_dev, OCT_PRIV_FLAG_TX_BYTES,3053			  intr_by_tx_bytes);3054	return 0;3055}3056 3057static int lio_get_fecparam(struct net_device *netdev,3058			    struct ethtool_fecparam *fec)3059{3060	struct lio *lio = GET_LIO(netdev);3061	struct octeon_device *oct = lio->oct_dev;3062 3063	fec->active_fec = ETHTOOL_FEC_NONE;3064	fec->fec = ETHTOOL_FEC_NONE;3065 3066	if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID ||3067	    oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) {3068		if (oct->no_speed_setting == 1)3069			return 0;3070 3071		liquidio_get_fec(lio);3072		fec->fec = (ETHTOOL_FEC_RS | ETHTOOL_FEC_OFF);3073		if (oct->props[lio->ifidx].fec == 1)3074			fec->active_fec = ETHTOOL_FEC_RS;3075		else3076			fec->active_fec = ETHTOOL_FEC_OFF;3077	}3078 3079	return 0;3080}3081 3082static int lio_set_fecparam(struct net_device *netdev,3083			    struct ethtool_fecparam *fec)3084{3085	struct lio *lio = GET_LIO(netdev);3086	struct octeon_device *oct = lio->oct_dev;3087 3088	if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID ||3089	    oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) {3090		if (oct->no_speed_setting == 1)3091			return -EOPNOTSUPP;3092 3093		if (fec->fec & ETHTOOL_FEC_OFF)3094			liquidio_set_fec(lio, 0);3095		else if (fec->fec & ETHTOOL_FEC_RS)3096			liquidio_set_fec(lio, 1);3097		else3098			return -EOPNOTSUPP;3099	} else {3100		return -EOPNOTSUPP;3101	}3102 3103	return 0;3104}3105 3106#define LIO_ETHTOOL_COALESCE	(ETHTOOL_COALESCE_RX_USECS |		\3107				 ETHTOOL_COALESCE_MAX_FRAMES |		\3108				 ETHTOOL_COALESCE_USE_ADAPTIVE |	\3109				 ETHTOOL_COALESCE_RX_MAX_FRAMES_LOW |	\3110				 ETHTOOL_COALESCE_TX_MAX_FRAMES_LOW |	\3111				 ETHTOOL_COALESCE_RX_MAX_FRAMES_HIGH |	\3112				 ETHTOOL_COALESCE_TX_MAX_FRAMES_HIGH |	\3113				 ETHTOOL_COALESCE_PKT_RATE_RX_USECS)3114 3115static const struct ethtool_ops lio_ethtool_ops = {3116	.supported_coalesce_params = LIO_ETHTOOL_COALESCE,3117	.get_link_ksettings	= lio_get_link_ksettings,3118	.set_link_ksettings	= lio_set_link_ksettings,3119	.get_fecparam		= lio_get_fecparam,3120	.set_fecparam		= lio_set_fecparam,3121	.get_link		= ethtool_op_get_link,3122	.get_drvinfo		= lio_get_drvinfo,3123	.get_ringparam		= lio_ethtool_get_ringparam,3124	.set_ringparam		= lio_ethtool_set_ringparam,3125	.get_channels		= lio_ethtool_get_channels,3126	.set_channels		= lio_ethtool_set_channels,3127	.set_phys_id		= lio_set_phys_id,3128	.get_eeprom_len		= lio_get_eeprom_len,3129	.get_eeprom		= lio_get_eeprom,3130	.get_strings		= lio_get_strings,3131	.get_ethtool_stats	= lio_get_ethtool_stats,3132	.get_pauseparam		= lio_get_pauseparam,3133	.set_pauseparam		= lio_set_pauseparam,3134	.get_regs_len		= lio_get_regs_len,3135	.get_regs		= lio_get_regs,3136	.get_msglevel		= lio_get_msglevel,3137	.set_msglevel		= lio_set_msglevel,3138	.get_sset_count		= lio_get_sset_count,3139	.get_coalesce		= lio_get_intr_coalesce,3140	.set_coalesce		= lio_set_intr_coalesce,3141	.get_priv_flags		= lio_get_priv_flags,3142	.set_priv_flags		= lio_set_priv_flags,3143#ifdef PTP_HARDWARE_TIMESTAMPING3144	.get_ts_info		= lio_get_ts_info,3145#endif3146};3147 3148static const struct ethtool_ops lio_vf_ethtool_ops = {3149	.supported_coalesce_params = LIO_ETHTOOL_COALESCE,3150	.get_link_ksettings	= lio_get_link_ksettings,3151	.get_link		= ethtool_op_get_link,3152	.get_drvinfo		= lio_get_vf_drvinfo,3153	.get_ringparam		= lio_ethtool_get_ringparam,3154	.set_ringparam          = lio_ethtool_set_ringparam,3155	.get_channels		= lio_ethtool_get_channels,3156	.set_channels		= lio_ethtool_set_channels,3157	.get_strings		= lio_vf_get_strings,3158	.get_ethtool_stats	= lio_vf_get_ethtool_stats,3159	.get_regs_len		= lio_get_regs_len,3160	.get_regs		= lio_get_regs,3161	.get_msglevel		= lio_get_msglevel,3162	.set_msglevel		= lio_vf_set_msglevel,3163	.get_sset_count		= lio_vf_get_sset_count,3164	.get_coalesce		= lio_get_intr_coalesce,3165	.set_coalesce		= lio_set_intr_coalesce,3166	.get_priv_flags		= lio_get_priv_flags,3167	.set_priv_flags		= lio_set_priv_flags,3168#ifdef PTP_HARDWARE_TIMESTAMPING3169	.get_ts_info		= lio_get_ts_info,3170#endif3171};3172 3173void liquidio_set_ethtool_ops(struct net_device *netdev)3174{3175	struct lio *lio = GET_LIO(netdev);3176	struct octeon_device *oct = lio->oct_dev;3177 3178	if (OCTEON_CN23XX_VF(oct))3179		netdev->ethtool_ops = &lio_vf_ethtool_ops;3180	else3181		netdev->ethtool_ops = &lio_ethtool_ops;3182}3183EXPORT_SYMBOL_GPL(liquidio_set_ethtool_ops);3184