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