Commit 86f968a0 authored by David S. Miller's avatar David S. Miller

Merge branch 'sfc-driver-for-EF100-family-NICs-part-1'

Edward Cree says:

====================
sfc: driver for EF100 family NICs, part 1

EF100 is a new NIC architecture under development at Xilinx, based
 partly on existing Solarflare technology.  As many of the hardware
 interfaces resemble EF10, support is implemented within the 'sfc'
 driver, which previous patch series "commonised" for this purpose.

In order to maintain bisectability while splitting into patches of a
 reasonable size, I had to do a certain amount of back-and-forth with
 stubs for things that the common code may try to call, mainly because
 we can't do them until we've set up MCDI, but we can't set up MCDI
 without probing the event queues, at which point a lot of the common
 machinery becomes reachable from event handlers.
Consequently, this first series doesn't get as far as actually sending
 and receiving packets.  I have a second series ready to follow it
 which implements the datapath (and a few other things like ethtool).

Changes from v4:
 * Fix build on CONFIG_RETPOLINE=n by using plain prototypes instead
   of INDIRECT_CALLABLE_DECLARE.

Changes from v3:
 * combine both drivers (sfc_ef100 and sfc) into a single module, to
   make non-modular builds work.  Patch #4 now adds a few indirections
   to support this; the ones in the RX and TX path use indirect-call-
   wrappers to minimise the performance impact.

Changes from v2:
 * remove MODULE_VERSION.
 * call efx_destroy_reset_workqueue() from ef100_exit_module().
 * correct uint32_ts to u32s.  While I was at it, I fixed a bunch of
   other style issues in the function-control-window code.
All in patch #4.

Changes from v1:
 * kernel test robot spotted a link error when sfc_ef100 was built
   without mdio.  It turns out the thing we were trying to link to
   was a bogus thing to do on anything but Falcon, so new patch #1
   removes it from this driver.
 * fix undeclared symbols in patch #4 by shuffling around prototypes
   and #includes and adding 'static' where appropriate.
 * fix uninitialised variable 'rc2' in patch #7.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 65ccbbda 1c748843
......@@ -17,7 +17,7 @@ config NET_VENDOR_SOLARFLARE
if NET_VENDOR_SOLARFLARE
config SFC
tristate "Solarflare SFC9000/SFC9100-family support"
tristate "Solarflare SFC9000/SFC9100/EF100-family support"
depends on PCI
select MDIO
select CRC32
......@@ -26,6 +26,9 @@ config SFC
This driver supports 10/40-gigabit Ethernet cards based on
the Solarflare SFC9000-family and SFC9100-family controllers.
It also supports 10/25/40/100-gigabit Ethernet cards based
on the Solarflare EF100 networking IP in Xilinx FPGAs.
To compile this driver as a module, choose M here. The module
will be called sfc.
config SFC_MTD
......
......@@ -4,7 +4,9 @@ sfc-y += efx.o efx_common.o efx_channels.o nic.o \
tx.o tx_common.o tx_tso.o rx.o rx_common.o \
selftest.o ethtool.o ethtool_common.o ptp.o \
mcdi.o mcdi_port.o mcdi_port_common.o \
mcdi_functions.o mcdi_filters.o mcdi_mon.o
mcdi_functions.o mcdi_filters.o mcdi_mon.o \
ef100.o ef100_nic.o ef100_netdev.o \
ef100_ethtool.o ef100_rx.o ef100_tx.o
sfc-$(CONFIG_SFC_MTD) += mtd.o
sfc-$(CONFIG_SFC_SRIOV) += sriov.o siena_sriov.o ef10_sriov.o
......
......@@ -6,6 +6,7 @@
#include "net_driver.h"
#include "rx_common.h"
#include "tx_common.h"
#include "ef10_regs.h"
#include "io.h"
#include "mcdi.h"
......@@ -3977,6 +3978,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.tx_remove = efx_mcdi_tx_remove,
.tx_write = efx_ef10_tx_write,
.tx_limit_len = efx_ef10_tx_limit_len,
.tx_enqueue = __efx_enqueue_skb,
.rx_push_rss_config = efx_mcdi_vf_rx_push_rss_config,
.rx_pull_rss_config = efx_mcdi_rx_pull_rss_config,
.rx_probe = efx_mcdi_rx_probe,
......@@ -3984,6 +3986,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.rx_remove = efx_mcdi_rx_remove,
.rx_write = efx_ef10_rx_write,
.rx_defer_refill = efx_ef10_rx_defer_refill,
.rx_packet = __efx_rx_packet,
.ev_probe = efx_mcdi_ev_probe,
.ev_init = efx_ef10_ev_init,
.ev_fini = efx_mcdi_ev_fini,
......@@ -4038,6 +4041,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.rx_hash_key_size = 40,
.check_caps = ef10_check_caps,
.print_additional_fwver = efx_ef10_print_additional_fwver,
.sensor_event = efx_mcdi_sensor_event,
};
const struct efx_nic_type efx_hunt_a0_nic_type = {
......@@ -4087,6 +4091,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.tx_remove = efx_mcdi_tx_remove,
.tx_write = efx_ef10_tx_write,
.tx_limit_len = efx_ef10_tx_limit_len,
.tx_enqueue = __efx_enqueue_skb,
.rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config,
.rx_pull_rss_config = efx_mcdi_rx_pull_rss_config,
.rx_push_rss_context_config = efx_mcdi_rx_push_rss_context_config,
......@@ -4097,6 +4102,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.rx_remove = efx_mcdi_rx_remove,
.rx_write = efx_ef10_rx_write,
.rx_defer_refill = efx_ef10_rx_defer_refill,
.rx_packet = __efx_rx_packet,
.ev_probe = efx_mcdi_ev_probe,
.ev_init = efx_ef10_ev_init,
.ev_fini = efx_mcdi_ev_fini,
......@@ -4172,4 +4178,5 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.rx_hash_key_size = 40,
.check_caps = ef10_check_caps,
.print_additional_fwver = efx_ef10_print_additional_fwver,
.sensor_event = efx_mcdi_sensor_event,
};
// SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2005-2018 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include "net_driver.h"
#include <linux/module.h>
#include <linux/aer.h>
#include "efx_common.h"
#include "efx_channels.h"
#include "io.h"
#include "ef100_nic.h"
#include "ef100_netdev.h"
#include "ef100_regs.h"
#include "ef100.h"
#define EFX_EF100_PCI_DEFAULT_BAR 2
/* Number of bytes at start of vendor specified extended capability that indicate
* that the capability is vendor specified. i.e. offset from value returned by
* pci_find_next_ext_capability() to beginning of vendor specified capability
* header.
*/
#define PCI_EXT_CAP_HDR_LENGTH 4
/* Expected size of a Xilinx continuation address table entry. */
#define ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH 16
struct ef100_func_ctl_window {
bool valid;
unsigned int bar;
u64 offset;
};
static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset,
struct ef100_func_ctl_window *result);
/* Number of bytes to offset when reading bit position x with dword accessors. */
#define ROUND_DOWN_TO_DWORD(x) (((x) & (~31)) >> 3)
#define EXTRACT_BITS(x, lbn, width) \
(((x) >> ((lbn) & 31)) & ((1ull << (width)) - 1))
static u32 _ef100_pci_get_bar_bits_with_width(struct efx_nic *efx,
int structure_start,
int lbn, int width)
{
efx_dword_t dword;
efx_readd(efx, &dword, structure_start + ROUND_DOWN_TO_DWORD(lbn));
return EXTRACT_BITS(le32_to_cpu(dword.u32[0]), lbn, width);
}
#define ef100_pci_get_bar_bits(efx, entry_location, bitdef) \
_ef100_pci_get_bar_bits_with_width(efx, entry_location, \
ESF_GZ_CFGBAR_ ## bitdef ## _LBN, \
ESF_GZ_CFGBAR_ ## bitdef ## _WIDTH)
static int ef100_pci_parse_ef100_entry(struct efx_nic *efx, int entry_location,
struct ef100_func_ctl_window *result)
{
u64 offset = ef100_pci_get_bar_bits(efx, entry_location, EF100_FUNC_CTL_WIN_OFF) <<
ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT;
u32 bar = ef100_pci_get_bar_bits(efx, entry_location, EF100_BAR);
netif_dbg(efx, probe, efx->net_dev,
"Found EF100 function control window bar=%d offset=0x%llx\n",
bar, offset);
if (result->valid) {
netif_err(efx, probe, efx->net_dev,
"Duplicated EF100 table entry.\n");
return -EINVAL;
}
if (bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_EXPANSION_ROM ||
bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_INVALID) {
netif_err(efx, probe, efx->net_dev,
"Bad BAR value of %d in Xilinx capabilities EF100 entry.\n",
bar);
return -EINVAL;
}
result->bar = bar;
result->offset = offset;
result->valid = true;
return 0;
}
static bool ef100_pci_does_bar_overflow(struct efx_nic *efx, int bar,
u64 next_entry)
{
return next_entry + ESE_GZ_CFGBAR_ENTRY_HEADER_SIZE >
pci_resource_len(efx->pci_dev, bar);
}
/* Parse a Xilinx capabilities table entry describing a continuation to a new
* sub-table.
*/
static int ef100_pci_parse_continue_entry(struct efx_nic *efx, int entry_location,
struct ef100_func_ctl_window *result)
{
unsigned int previous_bar;
efx_oword_t entry;
u64 offset;
int rc = 0;
u32 bar;
efx_reado(efx, &entry, entry_location);
bar = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_CONT_CAP_BAR);
offset = EFX_OWORD_FIELD64(entry, ESF_GZ_CFGBAR_CONT_CAP_OFFSET) <<
ESE_GZ_CONT_CAP_OFFSET_BYTES_SHIFT;
previous_bar = efx->mem_bar;
if (bar == ESE_GZ_VSEC_BAR_NUM_EXPANSION_ROM ||
bar == ESE_GZ_VSEC_BAR_NUM_INVALID) {
netif_err(efx, probe, efx->net_dev,
"Bad BAR value of %d in Xilinx capabilities sub-table.\n",
bar);
return -EINVAL;
}
if (bar != previous_bar) {
efx_fini_io(efx);
if (ef100_pci_does_bar_overflow(efx, bar, offset)) {
netif_err(efx, probe, efx->net_dev,
"Xilinx table will overrun BAR[%d] offset=0x%llx\n",
bar, offset);
return -EINVAL;
}
/* Temporarily map new BAR. */
rc = efx_init_io(efx, bar,
DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
pci_resource_len(efx->pci_dev, bar));
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Mapping new BAR for Xilinx table failed, rc=%d\n", rc);
return rc;
}
}
rc = ef100_pci_walk_xilinx_table(efx, offset, result);
if (rc)
return rc;
if (bar != previous_bar) {
efx_fini_io(efx);
/* Put old BAR back. */
rc = efx_init_io(efx, previous_bar,
DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
pci_resource_len(efx->pci_dev, previous_bar));
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Putting old BAR back failed, rc=%d\n", rc);
return rc;
}
}
return 0;
}
/* Iterate over the Xilinx capabilities table in the currently mapped BAR and
* call ef100_pci_parse_ef100_entry() on any EF100 entries and
* ef100_pci_parse_continue_entry() on any table continuations.
*/
static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset,
struct ef100_func_ctl_window *result)
{
u64 current_entry = offset;
int rc = 0;
while (true) {
u32 id = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_FORMAT);
u32 last = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_LAST);
u32 rev = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_REV);
u32 entry_size;
if (id == ESE_GZ_CFGBAR_ENTRY_LAST)
return 0;
entry_size = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_SIZE);
netif_dbg(efx, probe, efx->net_dev,
"Seen Xilinx table entry 0x%x size 0x%x at 0x%llx in BAR[%d]\n",
id, entry_size, current_entry, efx->mem_bar);
if (entry_size < sizeof(u32) * 2) {
netif_err(efx, probe, efx->net_dev,
"Xilinx table entry too short len=0x%x\n", entry_size);
return -EINVAL;
}
switch (id) {
case ESE_GZ_CFGBAR_ENTRY_EF100:
if (rev != ESE_GZ_CFGBAR_ENTRY_REV_EF100 ||
entry_size < ESE_GZ_CFGBAR_ENTRY_SIZE_EF100) {
netif_err(efx, probe, efx->net_dev,
"Bad length or rev for EF100 entry in Xilinx capabilities table. entry_size=%d rev=%d.\n",
entry_size, rev);
return -EINVAL;
}
rc = ef100_pci_parse_ef100_entry(efx, current_entry,
result);
if (rc)
return rc;
break;
case ESE_GZ_CFGBAR_ENTRY_CONT_CAP_ADDR:
if (rev != 0 || entry_size < ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH) {
netif_err(efx, probe, efx->net_dev,
"Bad length or rev for continue entry in Xilinx capabilities table. entry_size=%d rev=%d.\n",
entry_size, rev);
return -EINVAL;
}
rc = ef100_pci_parse_continue_entry(efx, current_entry, result);
if (rc)
return rc;
break;
default:
/* Ignore unknown table entries. */
break;
}
if (last)
return 0;
current_entry += entry_size;
if (ef100_pci_does_bar_overflow(efx, efx->mem_bar, current_entry)) {
netif_err(efx, probe, efx->net_dev,
"Xilinx table overrun at position=0x%llx.\n",
current_entry);
return -EINVAL;
}
}
}
static int _ef100_pci_get_config_bits_with_width(struct efx_nic *efx,
int structure_start, int lbn,
int width, u32 *result)
{
int rc, pos = structure_start + ROUND_DOWN_TO_DWORD(lbn);
u32 temp;
rc = pci_read_config_dword(efx->pci_dev, pos, &temp);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Failed to read PCI config dword at %d\n",
pos);
return rc;
}
*result = EXTRACT_BITS(temp, lbn, width);
return 0;
}
#define ef100_pci_get_config_bits(efx, entry_location, bitdef, result) \
_ef100_pci_get_config_bits_with_width(efx, entry_location, \
ESF_GZ_VSEC_ ## bitdef ## _LBN, \
ESF_GZ_VSEC_ ## bitdef ## _WIDTH, result)
/* Call ef100_pci_walk_xilinx_table() for the Xilinx capabilities table pointed
* to by this PCI_EXT_CAP_ID_VNDR.
*/
static int ef100_pci_parse_xilinx_cap(struct efx_nic *efx, int vndr_cap,
bool has_offset_hi,
struct ef100_func_ctl_window *result)
{
u32 offset_high = 0;
u32 offset_lo = 0;
u64 offset = 0;
u32 bar = 0;
int rc = 0;
rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_BAR, &bar);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Failed to read ESF_GZ_VSEC_TBL_BAR, rc=%d\n",
rc);
return rc;
}
if (bar == ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_EXPANSION_ROM ||
bar == ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_INVALID) {
netif_err(efx, probe, efx->net_dev,
"Bad BAR value of %d in Xilinx capabilities sub-table.\n",
bar);
return -EINVAL;
}
rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_OFF_LO, &offset_lo);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Failed to read ESF_GZ_VSEC_TBL_OFF_LO, rc=%d\n",
rc);
return rc;
}
/* Get optional extension to 64bit offset. */
if (has_offset_hi) {
rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_OFF_HI, &offset_high);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Failed to read ESF_GZ_VSEC_TBL_OFF_HI, rc=%d\n",
rc);
return rc;
}
}
offset = (((u64)offset_lo) << ESE_GZ_VSEC_TBL_OFF_LO_BYTES_SHIFT) |
(((u64)offset_high) << ESE_GZ_VSEC_TBL_OFF_HI_BYTES_SHIFT);
if (offset > pci_resource_len(efx->pci_dev, bar) - sizeof(u32) * 2) {
netif_err(efx, probe, efx->net_dev,
"Xilinx table will overrun BAR[%d] offset=0x%llx\n",
bar, offset);
return -EINVAL;
}
/* Temporarily map BAR. */
rc = efx_init_io(efx, bar,
DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
pci_resource_len(efx->pci_dev, bar));
if (rc) {
netif_err(efx, probe, efx->net_dev,
"efx_init_io failed, rc=%d\n", rc);
return rc;
}
rc = ef100_pci_walk_xilinx_table(efx, offset, result);
/* Unmap temporarily mapped BAR. */
efx_fini_io(efx);
return rc;
}
/* Call ef100_pci_parse_ef100_entry() for each Xilinx PCI_EXT_CAP_ID_VNDR
* capability.
*/
static int ef100_pci_find_func_ctrl_window(struct efx_nic *efx,
struct ef100_func_ctl_window *result)
{
int num_xilinx_caps = 0;
int cap = 0;
result->valid = false;
while ((cap = pci_find_next_ext_capability(efx->pci_dev, cap, PCI_EXT_CAP_ID_VNDR)) != 0) {
int vndr_cap = cap + PCI_EXT_CAP_HDR_LENGTH;
u32 vsec_ver = 0;
u32 vsec_len = 0;
u32 vsec_id = 0;
int rc = 0;
num_xilinx_caps++;
rc = ef100_pci_get_config_bits(efx, vndr_cap, ID, &vsec_id);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Failed to read ESF_GZ_VSEC_ID, rc=%d\n",
rc);
return rc;
}
rc = ef100_pci_get_config_bits(efx, vndr_cap, VER, &vsec_ver);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Failed to read ESF_GZ_VSEC_VER, rc=%d\n",
rc);
return rc;
}
/* Get length of whole capability - i.e. starting at cap */
rc = ef100_pci_get_config_bits(efx, vndr_cap, LEN, &vsec_len);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Failed to read ESF_GZ_VSEC_LEN, rc=%d\n",
rc);
return rc;
}
if (vsec_id == ESE_GZ_XILINX_VSEC_ID &&
vsec_ver == ESE_GZ_VSEC_VER_XIL_CFGBAR &&
vsec_len >= ESE_GZ_VSEC_LEN_MIN) {
bool has_offset_hi = (vsec_len >= ESE_GZ_VSEC_LEN_HIGH_OFFT);
rc = ef100_pci_parse_xilinx_cap(efx, vndr_cap,
has_offset_hi, result);
if (rc)
return rc;
}
}
if (num_xilinx_caps && !result->valid) {
netif_err(efx, probe, efx->net_dev,
"Seen %d Xilinx tables, but no EF100 entry.\n",
num_xilinx_caps);
return -EINVAL;
}
return 0;
}
/* Final NIC shutdown
* This is called only at module unload (or hotplug removal). A PF can call
* this on its VFs to ensure they are unbound first.
*/
static void ef100_pci_remove(struct pci_dev *pci_dev)
{
struct efx_nic *efx;
efx = pci_get_drvdata(pci_dev);
if (!efx)
return;
rtnl_lock();
dev_close(efx->net_dev);
rtnl_unlock();
/* Unregistering our netdev notifier triggers unbinding of TC indirect
* blocks, so we have to do it before PCI removal.
*/
unregister_netdevice_notifier(&efx->netdev_notifier);
ef100_remove(efx);
efx_fini_io(efx);
netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n");
pci_set_drvdata(pci_dev, NULL);
efx_fini_struct(efx);
free_netdev(efx->net_dev);
pci_disable_pcie_error_reporting(pci_dev);
};
static int ef100_pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *entry)
{
struct ef100_func_ctl_window fcw = { 0 };
struct net_device *net_dev;
struct efx_nic *efx;
int rc;
/* Allocate and initialise a struct net_device and struct efx_nic */
net_dev = alloc_etherdev_mq(sizeof(*efx), EFX_MAX_CORE_TX_QUEUES);
if (!net_dev)
return -ENOMEM;
efx = netdev_priv(net_dev);
efx->type = (const struct efx_nic_type *)entry->driver_data;
pci_set_drvdata(pci_dev, efx);
SET_NETDEV_DEV(net_dev, &pci_dev->dev);
rc = efx_init_struct(efx, pci_dev, net_dev);
if (rc)
goto fail;
efx->vi_stride = EF100_DEFAULT_VI_STRIDE;
netif_info(efx, probe, efx->net_dev,
"Solarflare EF100 NIC detected\n");
rc = ef100_pci_find_func_ctrl_window(efx, &fcw);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Error looking for ef100 function control window, rc=%d\n",
rc);
goto fail;
}
if (!fcw.valid) {
/* Extended capability not found - use defaults. */
fcw.bar = EFX_EF100_PCI_DEFAULT_BAR;
fcw.offset = 0;
fcw.valid = true;
}
if (fcw.offset > pci_resource_len(efx->pci_dev, fcw.bar) - ESE_GZ_FCW_LEN) {
netif_err(efx, probe, efx->net_dev,
"Func control window overruns BAR\n");
goto fail;
}
/* Set up basic I/O (BAR mappings etc) */
rc = efx_init_io(efx, fcw.bar,
DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
pci_resource_len(efx->pci_dev, fcw.bar));
if (rc)
goto fail;
efx->reg_base = fcw.offset;
efx->netdev_notifier.notifier_call = ef100_netdev_event;
rc = register_netdevice_notifier(&efx->netdev_notifier);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Failed to register netdevice notifier, rc=%d\n", rc);
goto fail;
}
rc = efx->type->probe(efx);
if (rc)
goto fail;
netif_dbg(efx, probe, efx->net_dev, "initialisation successful\n");
return 0;
fail:
ef100_pci_remove(pci_dev);
return rc;
}
/* PCI device ID table */
static const struct pci_device_id ef100_pci_table[] = {
{PCI_DEVICE(PCI_VENDOR_ID_XILINX, 0x0100), /* Riverhead PF */
.driver_data = (unsigned long) &ef100_pf_nic_type },
{0} /* end of list */
};
struct pci_driver ef100_pci_driver = {
.name = "sfc_ef100",
.id_table = ef100_pci_table,
.probe = ef100_pci_probe,
.remove = ef100_pci_remove,
.err_handler = &efx_err_handlers,
};
MODULE_DEVICE_TABLE(pci, ef100_pci_table);
/* SPDX-License-Identifier: GPL-2.0-only */
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2018 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
extern struct pci_driver ef100_pci_driver;
// SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2018 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include <linux/module.h>
#include <linux/netdevice.h>
#include "net_driver.h"
#include "efx.h"
#include "mcdi_port_common.h"
#include "ethtool_common.h"
#include "ef100_ethtool.h"
#include "mcdi_functions.h"
/* Ethtool options available
*/
const struct ethtool_ops ef100_ethtool_ops = {
.get_drvinfo = efx_ethtool_get_drvinfo,
};
/* SPDX-License-Identifier: GPL-2.0-only */
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2018 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
extern const struct ethtool_ops ef100_ethtool_ops;
// SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2018 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include "net_driver.h"
#include "mcdi_port_common.h"
#include "mcdi_functions.h"
#include "efx_common.h"
#include "efx_channels.h"
#include "tx_common.h"
#include "ef100_netdev.h"
#include "ef100_ethtool.h"
#include "efx_common.h"
#include "nic_common.h"
#include "ef100_nic.h"
#include "ef100_tx.h"
#include "ef100_regs.h"
#include "mcdi_filters.h"
#include "rx_common.h"
static void ef100_update_name(struct efx_nic *efx)
{
strcpy(efx->name, efx->net_dev->name);
}
static int ef100_alloc_vis(struct efx_nic *efx, unsigned int *allocated_vis)
{
/* EF100 uses a single TXQ per channel, as all checksum offloading
* is configured in the TX descriptor, and there is no TX Pacer for
* HIGHPRI queues.
*/
unsigned int tx_vis = efx->n_tx_channels + efx->n_extra_tx_channels;
unsigned int rx_vis = efx->n_rx_channels;
unsigned int min_vis, max_vis;
EFX_WARN_ON_PARANOID(efx->tx_queues_per_channel != 1);
tx_vis += efx->n_xdp_channels * efx->xdp_tx_per_channel;
max_vis = max(rx_vis, tx_vis);
/* Currently don't handle resource starvation and only accept
* our maximum needs and no less.
*/
min_vis = max_vis;
return efx_mcdi_alloc_vis(efx, min_vis, max_vis,
NULL, allocated_vis);
}
static int ef100_remap_bar(struct efx_nic *efx, int max_vis)
{
unsigned int uc_mem_map_size;
void __iomem *membase;
efx->max_vis = max_vis;
uc_mem_map_size = PAGE_ALIGN(max_vis * efx->vi_stride);
/* Extend the original UC mapping of the memory BAR */
membase = ioremap(efx->membase_phys, uc_mem_map_size);
if (!membase) {
netif_err(efx, probe, efx->net_dev,
"could not extend memory BAR to %x\n",
uc_mem_map_size);
return -ENOMEM;
}
iounmap(efx->membase);
efx->membase = membase;
return 0;
}
/* Context: process, rtnl_lock() held.
* Note that the kernel will ignore our return code; this method
* should really be a void.
*/
static int ef100_net_stop(struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
netif_dbg(efx, ifdown, efx->net_dev, "closing on CPU %d\n",
raw_smp_processor_id());
netif_stop_queue(net_dev);
efx_stop_all(efx);
efx_disable_interrupts(efx);
efx_clear_interrupt_affinity(efx);
efx_nic_fini_interrupt(efx);
efx_fini_napi(efx);
efx_remove_channels(efx);
efx_mcdi_free_vis(efx);
efx_remove_interrupts(efx);
return 0;
}
/* Context: process, rtnl_lock() held. */
static int ef100_net_open(struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
unsigned int allocated_vis;
int rc;
ef100_update_name(efx);
netif_dbg(efx, ifup, net_dev, "opening device on CPU %d\n",
raw_smp_processor_id());
rc = efx_check_disabled(efx);
if (rc)
goto fail;
rc = efx_probe_interrupts(efx);
if (rc)
goto fail;
rc = efx_set_channels(efx);
if (rc)
goto fail;
rc = efx_mcdi_free_vis(efx);
if (rc)
goto fail;
rc = ef100_alloc_vis(efx, &allocated_vis);
if (rc)
goto fail;
rc = efx_probe_channels(efx);
if (rc)
return rc;
rc = ef100_remap_bar(efx, allocated_vis);
if (rc)
goto fail;
efx_init_napi(efx);
rc = efx_nic_init_interrupt(efx);
if (rc)
goto fail;
efx_set_interrupt_affinity(efx);
rc = efx_enable_interrupts(efx);
if (rc)
goto fail;
/* in case the MC rebooted while we were stopped, consume the change
* to the warm reboot count
*/
(void) efx_mcdi_poll_reboot(efx);
efx_start_all(efx);
/* Link state detection is normally event-driven; we have
* to poll now because we could have missed a change
*/
mutex_lock(&efx->mac_lock);
if (efx_mcdi_phy_poll(efx))
efx_link_status_changed(efx);
mutex_unlock(&efx->mac_lock);
return 0;
fail:
ef100_net_stop(net_dev);
return rc;
}
/* Initiate a packet transmission. We use one channel per CPU
* (sharing when we have more CPUs than channels).
*
* Context: non-blocking.
* Note that returning anything other than NETDEV_TX_OK will cause the
* OS to free the skb.
*/
static netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb,
struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_tx_queue *tx_queue;
struct efx_channel *channel;
int rc;
channel = efx_get_tx_channel(efx, skb_get_queue_mapping(skb));
netif_vdbg(efx, tx_queued, efx->net_dev,
"%s len %d data %d channel %d\n", __func__,
skb->len, skb->data_len, channel->channel);
if (!efx->n_channels || !efx->n_tx_channels || !channel) {
netif_stop_queue(net_dev);
goto err;
}
tx_queue = &channel->tx_queue[0];
rc = ef100_enqueue_skb(tx_queue, skb);
if (rc == 0)
return NETDEV_TX_OK;
err:
net_dev->stats.tx_dropped++;
return NETDEV_TX_OK;
}
static const struct net_device_ops ef100_netdev_ops = {
.ndo_open = ef100_net_open,
.ndo_stop = ef100_net_stop,
.ndo_start_xmit = ef100_hard_start_xmit,
.ndo_get_phys_port_id = efx_get_phys_port_id,
.ndo_get_phys_port_name = efx_get_phys_port_name,
};
/* Netdev registration
*/
int ef100_netdev_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct efx_nic *efx = container_of(this, struct efx_nic, netdev_notifier);
struct net_device *net_dev = netdev_notifier_info_to_dev(ptr);
if (netdev_priv(net_dev) == efx && event == NETDEV_CHANGENAME)
ef100_update_name(efx);
return NOTIFY_DONE;
}
int ef100_register_netdev(struct efx_nic *efx)
{
struct net_device *net_dev = efx->net_dev;
int rc;
net_dev->watchdog_timeo = 5 * HZ;
net_dev->irq = efx->pci_dev->irq;
net_dev->netdev_ops = &ef100_netdev_ops;
net_dev->min_mtu = EFX_MIN_MTU;
net_dev->max_mtu = EFX_MAX_MTU;
net_dev->ethtool_ops = &ef100_ethtool_ops;
rtnl_lock();
rc = dev_alloc_name(net_dev, net_dev->name);
if (rc < 0)
goto fail_locked;
ef100_update_name(efx);
rc = register_netdevice(net_dev);
if (rc)
goto fail_locked;
/* Always start with carrier off; PHY events will detect the link */
netif_carrier_off(net_dev);
efx->state = STATE_READY;
rtnl_unlock();
efx_init_mcdi_logging(efx);
return 0;
fail_locked:
rtnl_unlock();
netif_err(efx, drv, efx->net_dev, "could not register net dev\n");
return rc;
}
void ef100_unregister_netdev(struct efx_nic *efx)
{
if (efx_dev_registered(efx)) {
efx_fini_mcdi_logging(efx);
efx->state = STATE_UNINIT;
unregister_netdev(efx->net_dev);
}
}
/* SPDX-License-Identifier: GPL-2.0-only */
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2018 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include <linux/netdevice.h>
int ef100_netdev_event(struct notifier_block *this,
unsigned long event, void *ptr);
int ef100_register_netdev(struct efx_nic *efx);
void ef100_unregister_netdev(struct efx_nic *efx);
// SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2018 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include "ef100_nic.h"
#include "efx_common.h"
#include "efx_channels.h"
#include "io.h"
#include "selftest.h"
#include "ef100_regs.h"
#include "mcdi.h"
#include "mcdi_pcol.h"
#include "mcdi_port_common.h"
#include "mcdi_functions.h"
#include "mcdi_filters.h"
#include "ef100_rx.h"
#include "ef100_tx.h"
#include "ef100_netdev.h"
#define EF100_MAX_VIS 4096
#define EF100_NUM_MCDI_BUFFERS 1
#define MCDI_BUF_LEN (8 + MCDI_CTL_SDU_LEN_MAX)
#define EF100_RESET_PORT ((ETH_RESET_MAC | ETH_RESET_PHY) << ETH_RESET_SHARED_SHIFT)
/* MCDI
*/
static u8 *ef100_mcdi_buf(struct efx_nic *efx, u8 bufid, dma_addr_t *dma_addr)
{
struct ef100_nic_data *nic_data = efx->nic_data;
if (dma_addr)
*dma_addr = nic_data->mcdi_buf.dma_addr +
bufid * ALIGN(MCDI_BUF_LEN, 256);
return nic_data->mcdi_buf.addr + bufid * ALIGN(MCDI_BUF_LEN, 256);
}
static int ef100_get_warm_boot_count(struct efx_nic *efx)
{
efx_dword_t reg;
efx_readd(efx, &reg, efx_reg(efx, ER_GZ_MC_SFT_STATUS));
if (EFX_DWORD_FIELD(reg, EFX_DWORD_0) == 0xffffffff) {
netif_err(efx, hw, efx->net_dev, "Hardware unavailable\n");
efx->state = STATE_DISABLED;
return -ENETDOWN;
} else {
return EFX_DWORD_FIELD(reg, EFX_WORD_1) == 0xb007 ?
EFX_DWORD_FIELD(reg, EFX_WORD_0) : -EIO;
}
}
static void ef100_mcdi_request(struct efx_nic *efx,
const efx_dword_t *hdr, size_t hdr_len,
const efx_dword_t *sdu, size_t sdu_len)
{
dma_addr_t dma_addr;
u8 *pdu = ef100_mcdi_buf(efx, 0, &dma_addr);
memcpy(pdu, hdr, hdr_len);
memcpy(pdu + hdr_len, sdu, sdu_len);
wmb();
/* The hardware provides 'low' and 'high' (doorbell) registers
* for passing the 64-bit address of an MCDI request to
* firmware. However the dwords are swapped by firmware. The
* least significant bits of the doorbell are then 0 for all
* MCDI requests due to alignment.
*/
_efx_writed(efx, cpu_to_le32((u64)dma_addr >> 32), efx_reg(efx, ER_GZ_MC_DB_LWRD));
_efx_writed(efx, cpu_to_le32((u32)dma_addr), efx_reg(efx, ER_GZ_MC_DB_HWRD));
}
static bool ef100_mcdi_poll_response(struct efx_nic *efx)
{
const efx_dword_t hdr =
*(const efx_dword_t *)(ef100_mcdi_buf(efx, 0, NULL));
rmb();
return EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE);
}
static void ef100_mcdi_read_response(struct efx_nic *efx,
efx_dword_t *outbuf, size_t offset,
size_t outlen)
{
const u8 *pdu = ef100_mcdi_buf(efx, 0, NULL);
memcpy(outbuf, pdu + offset, outlen);
}
static int ef100_mcdi_poll_reboot(struct efx_nic *efx)
{
struct ef100_nic_data *nic_data = efx->nic_data;
int rc;
rc = ef100_get_warm_boot_count(efx);
if (rc < 0) {
/* The firmware is presumably in the process of
* rebooting. However, we are supposed to report each
* reboot just once, so we must only do that once we
* can read and store the updated warm boot count.
*/
return 0;
}
if (rc == nic_data->warm_boot_count)
return 0;
nic_data->warm_boot_count = rc;
return -EIO;
}
static void ef100_mcdi_reboot_detected(struct efx_nic *efx)
{
}
/* MCDI calls
*/
static int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address)
{
MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
size_t outlen;
int rc;
BUILD_BUG_ON(MC_CMD_GET_MAC_ADDRESSES_IN_LEN != 0);
rc = efx_mcdi_rpc(efx, MC_CMD_GET_MAC_ADDRESSES, NULL, 0,
outbuf, sizeof(outbuf), &outlen);
if (rc)
return rc;
if (outlen < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)
return -EIO;
ether_addr_copy(mac_address,
MCDI_PTR(outbuf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE));
return 0;
}
static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
{
MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN);
struct ef100_nic_data *nic_data = efx->nic_data;
u8 vi_window_mode;
size_t outlen;
int rc;
BUILD_BUG_ON(MC_CMD_GET_CAPABILITIES_IN_LEN != 0);
rc = efx_mcdi_rpc(efx, MC_CMD_GET_CAPABILITIES, NULL, 0,
outbuf, sizeof(outbuf), &outlen);
if (rc)
return rc;
if (outlen < MC_CMD_GET_CAPABILITIES_V4_OUT_LEN) {
netif_err(efx, drv, efx->net_dev,
"unable to read datapath firmware capabilities\n");
return -EIO;
}
nic_data->datapath_caps = MCDI_DWORD(outbuf,
GET_CAPABILITIES_OUT_FLAGS1);
nic_data->datapath_caps2 = MCDI_DWORD(outbuf,
GET_CAPABILITIES_V2_OUT_FLAGS2);
if (outlen < MC_CMD_GET_CAPABILITIES_V7_OUT_LEN)
nic_data->datapath_caps3 = 0;
else
nic_data->datapath_caps3 = MCDI_DWORD(outbuf,
GET_CAPABILITIES_V7_OUT_FLAGS3);
vi_window_mode = MCDI_BYTE(outbuf,
GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE);
rc = efx_mcdi_window_mode_to_stride(efx, vi_window_mode);
if (rc)
return rc;
if (efx_ef100_has_cap(nic_data->datapath_caps2, TX_TSO_V3))
efx->net_dev->features |= NETIF_F_TSO | NETIF_F_TSO6;
efx->num_mac_stats = MCDI_WORD(outbuf,
GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS);
netif_dbg(efx, probe, efx->net_dev,
"firmware reports num_mac_stats = %u\n",
efx->num_mac_stats);
return 0;
}
/* Event handling
*/
static int ef100_ev_probe(struct efx_channel *channel)
{
/* Allocate an extra descriptor for the QMDA status completion entry */
return efx_nic_alloc_buffer(channel->efx, &channel->eventq.buf,
(channel->eventq_mask + 2) *
sizeof(efx_qword_t),
GFP_KERNEL);
}
static int ef100_ev_init(struct efx_channel *channel)
{
struct ef100_nic_data *nic_data = channel->efx->nic_data;
/* initial phase is 0 */
clear_bit(channel->channel, nic_data->evq_phases);
return efx_mcdi_ev_init(channel, false, false);
}
static void ef100_ev_read_ack(struct efx_channel *channel)
{
efx_dword_t evq_prime;
EFX_POPULATE_DWORD_2(evq_prime,
ERF_GZ_EVQ_ID, channel->channel,
ERF_GZ_IDX, channel->eventq_read_ptr &
channel->eventq_mask);
efx_writed(channel->efx, &evq_prime,
efx_reg(channel->efx, ER_GZ_EVQ_INT_PRIME));
}
static int ef100_ev_process(struct efx_channel *channel, int quota)
{
struct efx_nic *efx = channel->efx;
struct ef100_nic_data *nic_data;
bool evq_phase, old_evq_phase;
unsigned int read_ptr;
efx_qword_t *p_event;
int spent = 0;
bool ev_phase;
int ev_type;
if (unlikely(!channel->enabled))
return 0;
nic_data = efx->nic_data;
evq_phase = test_bit(channel->channel, nic_data->evq_phases);
old_evq_phase = evq_phase;
read_ptr = channel->eventq_read_ptr;
BUILD_BUG_ON(ESF_GZ_EV_RXPKTS_PHASE_LBN != ESF_GZ_EV_TXCMPL_PHASE_LBN);
while (spent < quota) {
p_event = efx_event(channel, read_ptr);
ev_phase = !!EFX_QWORD_FIELD(*p_event, ESF_GZ_EV_RXPKTS_PHASE);
if (ev_phase != evq_phase)
break;
netif_vdbg(efx, drv, efx->net_dev,
"processing event on %d " EFX_QWORD_FMT "\n",
channel->channel, EFX_QWORD_VAL(*p_event));
ev_type = EFX_QWORD_FIELD(*p_event, ESF_GZ_E_TYPE);
switch (ev_type) {
case ESE_GZ_EF100_EV_MCDI:
efx_mcdi_process_event(channel, p_event);
break;
case ESE_GZ_EF100_EV_DRIVER:
netif_info(efx, drv, efx->net_dev,
"Driver initiated event " EFX_QWORD_FMT "\n",
EFX_QWORD_VAL(*p_event));
break;
default:
netif_info(efx, drv, efx->net_dev,
"Unhandled event " EFX_QWORD_FMT "\n",
EFX_QWORD_VAL(*p_event));
}
++read_ptr;
if ((read_ptr & channel->eventq_mask) == 0)
evq_phase = !evq_phase;
}
channel->eventq_read_ptr = read_ptr;
if (evq_phase != old_evq_phase)
change_bit(channel->channel, nic_data->evq_phases);
return spent;
}
static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id)
{
struct efx_msi_context *context = dev_id;
struct efx_nic *efx = context->efx;
netif_vdbg(efx, intr, efx->net_dev,
"IRQ %d on CPU %d\n", irq, raw_smp_processor_id());
if (likely(READ_ONCE(efx->irq_soft_enabled))) {
/* Note test interrupts */
if (context->index == efx->irq_level)
efx->last_irq_cpu = raw_smp_processor_id();
/* Schedule processing of the channel */
efx_schedule_channel_irq(efx->channel[context->index]);
}
return IRQ_HANDLED;
}
static int ef100_phy_probe(struct efx_nic *efx)
{
struct efx_mcdi_phy_data *phy_data;
int rc;
/* Probe for the PHY */
efx->phy_data = kzalloc(sizeof(struct efx_mcdi_phy_data), GFP_KERNEL);
if (!efx->phy_data)
return -ENOMEM;
rc = efx_mcdi_get_phy_cfg(efx, efx->phy_data);
if (rc)
return rc;
/* Populate driver and ethtool settings */
phy_data = efx->phy_data;
mcdi_to_ethtool_linkset(phy_data->media, phy_data->supported_cap,
efx->link_advertising);
efx->fec_config = mcdi_fec_caps_to_ethtool(phy_data->supported_cap,
false);
/* Default to Autonegotiated flow control if the PHY supports it */
efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
efx->wanted_fc |= EFX_FC_AUTO;
efx_link_set_wanted_fc(efx, efx->wanted_fc);
/* Push settings to the PHY. Failure is not fatal, the user can try to
* fix it using ethtool.
*/
rc = efx_mcdi_port_reconfigure(efx);
if (rc && rc != -EPERM)
netif_warn(efx, drv, efx->net_dev,
"could not initialise PHY settings\n");
return 0;
}
/* Other
*/
static int ef100_reconfigure_mac(struct efx_nic *efx, bool mtu_only)
{
WARN_ON(!mutex_is_locked(&efx->mac_lock));
efx_mcdi_filter_sync_rx_mode(efx);
if (mtu_only && efx_has_cap(efx, SET_MAC_ENHANCED))
return efx_mcdi_set_mtu(efx);
return efx_mcdi_set_mac(efx);
}
static enum reset_type ef100_map_reset_reason(enum reset_type reason)
{
if (reason == RESET_TYPE_TX_WATCHDOG)
return reason;
return RESET_TYPE_DISABLE;
}
static int ef100_map_reset_flags(u32 *flags)
{
/* Only perform a RESET_TYPE_ALL because we don't support MC_REBOOTs */
if ((*flags & EF100_RESET_PORT)) {
*flags &= ~EF100_RESET_PORT;
return RESET_TYPE_ALL;
}
if (*flags & ETH_RESET_MGMT) {
*flags &= ~ETH_RESET_MGMT;
return RESET_TYPE_DISABLE;
}
return -EINVAL;
}
static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
{
int rc;
dev_close(efx->net_dev);
if (reset_type == RESET_TYPE_TX_WATCHDOG) {
netif_device_attach(efx->net_dev);
__clear_bit(reset_type, &efx->reset_pending);
rc = dev_open(efx->net_dev, NULL);
} else if (reset_type == RESET_TYPE_ALL) {
rc = efx_mcdi_reset(efx, reset_type);
if (rc)
return rc;
netif_device_attach(efx->net_dev);
rc = dev_open(efx->net_dev, NULL);
} else {
rc = 1; /* Leave the device closed */
}
return rc;
}
static int efx_ef100_get_phys_port_id(struct efx_nic *efx,
struct netdev_phys_item_id *ppid)
{
struct ef100_nic_data *nic_data = efx->nic_data;
if (!is_valid_ether_addr(nic_data->port_id))
return -EOPNOTSUPP;
ppid->id_len = ETH_ALEN;
memcpy(ppid->id, nic_data->port_id, ppid->id_len);
return 0;
}
static unsigned int ef100_check_caps(const struct efx_nic *efx,
u8 flag, u32 offset)
{
const struct ef100_nic_data *nic_data = efx->nic_data;
switch (offset) {
case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS1_OFST:
return nic_data->datapath_caps & BIT_ULL(flag);
case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS2_OFST:
return nic_data->datapath_caps2 & BIT_ULL(flag);
case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS3_OFST:
return nic_data->datapath_caps3 & BIT_ULL(flag);
default:
return 0;
}
}
/* NIC level access functions
*/
const struct efx_nic_type ef100_pf_nic_type = {
.revision = EFX_REV_EF100,
.is_vf = false,
.probe = ef100_probe_pf,
.mcdi_max_ver = 2,
.mcdi_request = ef100_mcdi_request,
.mcdi_poll_response = ef100_mcdi_poll_response,
.mcdi_read_response = ef100_mcdi_read_response,
.mcdi_poll_reboot = ef100_mcdi_poll_reboot,
.mcdi_reboot_detected = ef100_mcdi_reboot_detected,
.irq_enable_master = efx_port_dummy_op_void,
.irq_disable_non_ev = efx_port_dummy_op_void,
.push_irq_moderation = efx_channel_dummy_op_void,
.min_interrupt_mode = EFX_INT_MODE_MSIX,
.map_reset_reason = ef100_map_reset_reason,
.map_reset_flags = ef100_map_reset_flags,
.reset = ef100_reset,
.check_caps = ef100_check_caps,
.ev_probe = ef100_ev_probe,
.ev_init = ef100_ev_init,
.ev_fini = efx_mcdi_ev_fini,
.ev_remove = efx_mcdi_ev_remove,
.irq_handle_msi = ef100_msi_interrupt,
.ev_process = ef100_ev_process,
.ev_read_ack = ef100_ev_read_ack,
.tx_probe = ef100_tx_probe,
.tx_init = ef100_tx_init,
.tx_write = ef100_tx_write,
.tx_enqueue = ef100_enqueue_skb,
.rx_probe = efx_mcdi_rx_probe,
.rx_init = efx_mcdi_rx_init,
.rx_remove = efx_mcdi_rx_remove,
.rx_write = ef100_rx_write,
.rx_packet = __ef100_rx_packet,
.get_phys_port_id = efx_ef100_get_phys_port_id,
.reconfigure_mac = ef100_reconfigure_mac,
/* Per-type bar/size configuration not used on ef100. Location of
* registers is defined by extended capabilities.
*/
.mem_bar = NULL,
.mem_map_size = NULL,
};
/* NIC probe and remove
*/
static int ef100_probe_main(struct efx_nic *efx)
{
unsigned int bar_size = resource_size(&efx->pci_dev->resource[efx->mem_bar]);
struct net_device *net_dev = efx->net_dev;
struct ef100_nic_data *nic_data;
int i, rc;
if (WARN_ON(bar_size == 0))
return -EIO;
nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL);
if (!nic_data)
return -ENOMEM;
efx->nic_data = nic_data;
nic_data->efx = efx;
net_dev->features |= efx->type->offload_features;
net_dev->hw_features |= efx->type->offload_features;
/* we assume later that we can copy from this buffer in dwords */
BUILD_BUG_ON(MCDI_CTL_SDU_LEN_MAX_V2 % 4);
/* MCDI buffers must be 256 byte aligned. */
rc = efx_nic_alloc_buffer(efx, &nic_data->mcdi_buf, MCDI_BUF_LEN,
GFP_KERNEL);
if (rc)
goto fail;
/* Get the MC's warm boot count. In case it's rebooting right
* now, be prepared to retry.
*/
i = 0;
for (;;) {
rc = ef100_get_warm_boot_count(efx);
if (rc >= 0)
break;
if (++i == 5)
goto fail;
ssleep(1);
}
nic_data->warm_boot_count = rc;
/* In case we're recovering from a crash (kexec), we want to
* cancel any outstanding request by the previous user of this
* function. We send a special message using the least
* significant bits of the 'high' (doorbell) register.
*/
_efx_writed(efx, cpu_to_le32(1), efx_reg(efx, ER_GZ_MC_DB_HWRD));
/* Post-IO section. */
rc = efx_mcdi_init(efx);
if (!rc && efx->mcdi->fn_flags &
(1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT)) {
netif_info(efx, probe, efx->net_dev,
"No network port on this PCI function");
rc = -ENODEV;
}
if (rc)
goto fail;
/* Reset (most) configuration for this function */
rc = efx_mcdi_reset(efx, RESET_TYPE_ALL);
if (rc)
goto fail;
rc = efx_ef100_init_datapath_caps(efx);
if (rc < 0)
goto fail;
efx->max_vis = EF100_MAX_VIS;
rc = efx_mcdi_port_get_number(efx);
if (rc < 0)
goto fail;
efx->port_num = rc;
rc = ef100_phy_probe(efx);
if (rc)
goto fail;
rc = efx_init_channels(efx);
if (rc)
goto fail;
rc = ef100_register_netdev(efx);
if (rc)
goto fail;
return 0;
fail:
return rc;
}
int ef100_probe_pf(struct efx_nic *efx)
{
struct net_device *net_dev = efx->net_dev;
struct ef100_nic_data *nic_data;
int rc = ef100_probe_main(efx);
if (rc)
goto fail;
nic_data = efx->nic_data;
rc = ef100_get_mac_address(efx, net_dev->perm_addr);
if (rc)
goto fail;
/* Assign MAC address */
memcpy(net_dev->dev_addr, net_dev->perm_addr, ETH_ALEN);
memcpy(nic_data->port_id, net_dev->perm_addr, ETH_ALEN);
return 0;
fail:
return rc;
}
void ef100_remove(struct efx_nic *efx)
{
struct ef100_nic_data *nic_data = efx->nic_data;
ef100_unregister_netdev(efx);
efx_fini_channels(efx);
kfree(efx->phy_data);
efx->phy_data = NULL;
efx_mcdi_detach(efx);
efx_mcdi_fini(efx);
if (nic_data)
efx_nic_free_buffer(efx, &nic_data->mcdi_buf);
kfree(nic_data);
efx->nic_data = NULL;
}
/* SPDX-License-Identifier: GPL-2.0-only */
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2018 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include "net_driver.h"
#include "nic_common.h"
extern const struct efx_nic_type ef100_pf_nic_type;
int ef100_probe_pf(struct efx_nic *efx);
void ef100_remove(struct efx_nic *efx);
struct ef100_nic_data {
struct efx_nic *efx;
struct efx_buffer mcdi_buf;
u32 datapath_caps;
u32 datapath_caps2;
u32 datapath_caps3;
u16 warm_boot_count;
u8 port_id[ETH_ALEN];
DECLARE_BITMAP(evq_phases, EFX_MAX_CHANNELS);
};
#define efx_ef100_has_cap(caps, flag) \
(!!((caps) & BIT_ULL(MC_CMD_GET_CAPABILITIES_V4_OUT_ ## flag ## _LBN)))
/* SPDX-License-Identifier: GPL-2.0-only */
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2018 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_EF100_REGS_H
#define EFX_EF100_REGS_H
/* EF100 hardware architecture definitions have a name prefix following
* the format:
*
* E<type>_<min-rev><max-rev>_
*
* The following <type> strings are used:
*
* MMIO register Host memory structure
* -------------------------------------------------------------
* Address R
* Bitfield RF SF
* Enumerator FE SE
*
* <min-rev> is the first revision to which the definition applies:
*
* G: Riverhead
*
* If the definition has been changed or removed in later revisions
* then <max-rev> is the last revision to which the definition applies;
* otherwise it is "Z".
*/
/**************************************************************************
*
* EF100 registers and descriptors
*
**************************************************************************
*/
/* HW_REV_ID_REG: Hardware revision info register */
#define ER_GZ_HW_REV_ID 0x00000000
/* NIC_REV_ID: SoftNIC revision info register */
#define ER_GZ_NIC_REV_ID 0x00000004
/* NIC_MAGIC: Signature register that should contain a well-known value */
#define ER_GZ_NIC_MAGIC 0x00000008
#define ERF_GZ_NIC_MAGIC_LBN 0
#define ERF_GZ_NIC_MAGIC_WIDTH 32
#define EFE_GZ_NIC_MAGIC_EXPECTED 0xEF100FCB
/* MC_SFT_STATUS: MC soft status */
#define ER_GZ_MC_SFT_STATUS 0x00000010
#define ER_GZ_MC_SFT_STATUS_STEP 4
#define ER_GZ_MC_SFT_STATUS_ROWS 2
/* MC_DB_LWRD_REG: MC doorbell register, low word */
#define ER_GZ_MC_DB_LWRD 0x00000020
/* MC_DB_HWRD_REG: MC doorbell register, high word */
#define ER_GZ_MC_DB_HWRD 0x00000024
/* EVQ_INT_PRIME: Prime EVQ */
#define ER_GZ_EVQ_INT_PRIME 0x00000040
#define ERF_GZ_IDX_LBN 16
#define ERF_GZ_IDX_WIDTH 16
#define ERF_GZ_EVQ_ID_LBN 0
#define ERF_GZ_EVQ_ID_WIDTH 16
/* INT_AGG_RING_PRIME: Prime interrupt aggregation ring. */
#define ER_GZ_INT_AGG_RING_PRIME 0x00000048
/* defined as ERF_GZ_IDX_LBN 16; access=WO reset=0x0 */
/* defined as ERF_GZ_IDX_WIDTH 16 */
#define ERF_GZ_RING_ID_LBN 0
#define ERF_GZ_RING_ID_WIDTH 16
/* EVQ_TMR: EVQ timer control */
#define ER_GZ_EVQ_TMR 0x00000104
#define ER_GZ_EVQ_TMR_STEP 65536
#define ER_GZ_EVQ_TMR_ROWS 1024
/* EVQ_UNSOL_CREDIT_GRANT_SEQ: Grant credits for unsolicited events. */
#define ER_GZ_EVQ_UNSOL_CREDIT_GRANT_SEQ 0x00000108
#define ER_GZ_EVQ_UNSOL_CREDIT_GRANT_SEQ_STEP 65536
#define ER_GZ_EVQ_UNSOL_CREDIT_GRANT_SEQ_ROWS 1024
/* EVQ_DESC_CREDIT_GRANT_SEQ: Grant credits for descriptor proxy events. */
#define ER_GZ_EVQ_DESC_CREDIT_GRANT_SEQ 0x00000110
#define ER_GZ_EVQ_DESC_CREDIT_GRANT_SEQ_STEP 65536
#define ER_GZ_EVQ_DESC_CREDIT_GRANT_SEQ_ROWS 1024
/* RX_RING_DOORBELL: Ring Rx doorbell. */
#define ER_GZ_RX_RING_DOORBELL 0x00000180
#define ER_GZ_RX_RING_DOORBELL_STEP 65536
#define ER_GZ_RX_RING_DOORBELL_ROWS 1024
#define ERF_GZ_RX_RING_PIDX_LBN 16
#define ERF_GZ_RX_RING_PIDX_WIDTH 16
/* TX_RING_DOORBELL: Ring Tx doorbell. */
#define ER_GZ_TX_RING_DOORBELL 0x00000200
#define ER_GZ_TX_RING_DOORBELL_STEP 65536
#define ER_GZ_TX_RING_DOORBELL_ROWS 1024
#define ERF_GZ_TX_RING_PIDX_LBN 16
#define ERF_GZ_TX_RING_PIDX_WIDTH 16
/* TX_DESC_PUSH: Tx ring descriptor push. Reserved for future use. */
#define ER_GZ_TX_DESC_PUSH 0x00000210
#define ER_GZ_TX_DESC_PUSH_STEP 65536
#define ER_GZ_TX_DESC_PUSH_ROWS 1024
/* THE_TIME: NIC hardware time */
#define ER_GZ_THE_TIME 0x00000280
#define ER_GZ_THE_TIME_STEP 65536
#define ER_GZ_THE_TIME_ROWS 1024
#define ERF_GZ_THE_TIME_SECS_LBN 32
#define ERF_GZ_THE_TIME_SECS_WIDTH 32
#define ERF_GZ_THE_TIME_NANOS_LBN 2
#define ERF_GZ_THE_TIME_NANOS_WIDTH 30
#define ERF_GZ_THE_TIME_CLOCK_IN_SYNC_LBN 1
#define ERF_GZ_THE_TIME_CLOCK_IN_SYNC_WIDTH 1
#define ERF_GZ_THE_TIME_CLOCK_IS_SET_LBN 0
#define ERF_GZ_THE_TIME_CLOCK_IS_SET_WIDTH 1
/* PARAMS_TLV_LEN: Size of design parameters area in bytes */
#define ER_GZ_PARAMS_TLV_LEN 0x00000c00
#define ER_GZ_PARAMS_TLV_LEN_STEP 65536
#define ER_GZ_PARAMS_TLV_LEN_ROWS 1024
/* PARAMS_TLV: Design parameters */
#define ER_GZ_PARAMS_TLV 0x00000c04
#define ER_GZ_PARAMS_TLV_STEP 65536
#define ER_GZ_PARAMS_TLV_ROWS 1024
/* EW_EMBEDDED_EVENT */
#define ESF_GZ_EV_256_EVENT_LBN 0
#define ESF_GZ_EV_256_EVENT_WIDTH 64
#define ESE_GZ_EW_EMBEDDED_EVENT_STRUCT_SIZE 64
/* NMMU_PAGESZ_2M_ADDR */
#define ESF_GZ_NMMU_2M_PAGE_SIZE_ID_LBN 59
#define ESF_GZ_NMMU_2M_PAGE_SIZE_ID_WIDTH 5
#define ESE_GZ_NMMU_PAGE_SIZE_2M 9
#define ESF_GZ_NMMU_2M_PAGE_ID_LBN 21
#define ESF_GZ_NMMU_2M_PAGE_ID_WIDTH 38
#define ESF_GZ_NMMU_2M_PAGE_OFFSET_LBN 0
#define ESF_GZ_NMMU_2M_PAGE_OFFSET_WIDTH 21
#define ESE_GZ_NMMU_PAGESZ_2M_ADDR_STRUCT_SIZE 64
/* PARAM_TLV */
#define ESF_GZ_TLV_VALUE_LBN 16
#define ESF_GZ_TLV_VALUE_WIDTH 8
#define ESE_GZ_TLV_VALUE_LENMIN 8
#define ESE_GZ_TLV_VALUE_LENMAX 2040
#define ESF_GZ_TLV_LEN_LBN 8
#define ESF_GZ_TLV_LEN_WIDTH 8
#define ESF_GZ_TLV_TYPE_LBN 0
#define ESF_GZ_TLV_TYPE_WIDTH 8
#define ESE_GZ_DP_NMMU_GROUP_SIZE 5
#define ESE_GZ_DP_EVQ_UNSOL_CREDIT_SEQ_BITS 4
#define ESE_GZ_DP_TX_EV_NUM_DESCS_BITS 3
#define ESE_GZ_DP_RX_EV_NUM_PACKETS_BITS 2
#define ESE_GZ_DP_PARTIAL_TSTAMP_SUB_NANO_BITS 1
#define ESE_GZ_DP_PAD 0
#define ESE_GZ_PARAM_TLV_STRUCT_SIZE 24
/* PCI_EXPRESS_XCAP_HDR */
#define ESF_GZ_PCI_EXPRESS_XCAP_NEXT_LBN 20
#define ESF_GZ_PCI_EXPRESS_XCAP_NEXT_WIDTH 12
#define ESF_GZ_PCI_EXPRESS_XCAP_VER_LBN 16
#define ESF_GZ_PCI_EXPRESS_XCAP_VER_WIDTH 4
#define ESE_GZ_PCI_EXPRESS_XCAP_VER_VSEC 1
#define ESF_GZ_PCI_EXPRESS_XCAP_ID_LBN 0
#define ESF_GZ_PCI_EXPRESS_XCAP_ID_WIDTH 16
#define ESE_GZ_PCI_EXPRESS_XCAP_ID_VNDR 0xb
#define ESE_GZ_PCI_EXPRESS_XCAP_HDR_STRUCT_SIZE 32
/* RHEAD_BASE_EVENT */
#define ESF_GZ_E_TYPE_LBN 60
#define ESF_GZ_E_TYPE_WIDTH 4
#define ESE_GZ_EF100_EV_DRIVER 5
#define ESE_GZ_EF100_EV_MCDI 4
#define ESE_GZ_EF100_EV_CONTROL 3
#define ESE_GZ_EF100_EV_TX_TIMESTAMP 2
#define ESE_GZ_EF100_EV_TX_COMPLETION 1
#define ESE_GZ_EF100_EV_RX_PKTS 0
#define ESF_GZ_EV_EVQ_PHASE_LBN 59
#define ESF_GZ_EV_EVQ_PHASE_WIDTH 1
#define ESE_GZ_RHEAD_BASE_EVENT_STRUCT_SIZE 64
/* RHEAD_EW_EVENT */
#define ESF_GZ_EV_256_EV32_PHASE_LBN 255
#define ESF_GZ_EV_256_EV32_PHASE_WIDTH 1
#define ESF_GZ_EV_256_EV32_TYPE_LBN 251
#define ESF_GZ_EV_256_EV32_TYPE_WIDTH 4
#define ESE_GZ_EF100_EVEW_VIRTQ_DESC 2
#define ESE_GZ_EF100_EVEW_TXQ_DESC 1
#define ESE_GZ_EF100_EVEW_64BIT 0
#define ESE_GZ_RHEAD_EW_EVENT_STRUCT_SIZE 256
/* RX_DESC */
#define ESF_GZ_RX_BUF_ADDR_LBN 0
#define ESF_GZ_RX_BUF_ADDR_WIDTH 64
#define ESE_GZ_RX_DESC_STRUCT_SIZE 64
/* TXQ_DESC_PROXY_EVENT */
#define ESF_GZ_EV_TXQ_DP_VI_ID_LBN 128
#define ESF_GZ_EV_TXQ_DP_VI_ID_WIDTH 16
#define ESF_GZ_EV_TXQ_DP_TXQ_DESC_LBN 0
#define ESF_GZ_EV_TXQ_DP_TXQ_DESC_WIDTH 128
#define ESE_GZ_TXQ_DESC_PROXY_EVENT_STRUCT_SIZE 144
/* TX_DESC_TYPE */
#define ESF_GZ_TX_DESC_TYPE_LBN 124
#define ESF_GZ_TX_DESC_TYPE_WIDTH 4
#define ESE_GZ_TX_DESC_TYPE_DESC2CMPT 7
#define ESE_GZ_TX_DESC_TYPE_MEM2MEM 4
#define ESE_GZ_TX_DESC_TYPE_SEG 3
#define ESE_GZ_TX_DESC_TYPE_TSO 2
#define ESE_GZ_TX_DESC_TYPE_PREFIX 1
#define ESE_GZ_TX_DESC_TYPE_SEND 0
#define ESE_GZ_TX_DESC_TYPE_STRUCT_SIZE 128
/* VIRTQ_DESC_PROXY_EVENT */
#define ESF_GZ_EV_VQ_DP_AVAIL_ENTRY_LBN 144
#define ESF_GZ_EV_VQ_DP_AVAIL_ENTRY_WIDTH 16
#define ESF_GZ_EV_VQ_DP_VI_ID_LBN 128
#define ESF_GZ_EV_VQ_DP_VI_ID_WIDTH 16
#define ESF_GZ_EV_VQ_DP_VIRTQ_DESC_LBN 0
#define ESF_GZ_EV_VQ_DP_VIRTQ_DESC_WIDTH 128
#define ESE_GZ_VIRTQ_DESC_PROXY_EVENT_STRUCT_SIZE 160
/* XIL_CFGBAR_TBL_ENTRY */
#define ESF_GZ_CFGBAR_CONT_CAP_OFF_HI_LBN 96
#define ESF_GZ_CFGBAR_CONT_CAP_OFF_HI_WIDTH 32
#define ESF_GZ_CFGBAR_CONT_CAP_OFFSET_LBN 68
#define ESF_GZ_CFGBAR_CONT_CAP_OFFSET_WIDTH 60
#define ESE_GZ_CONT_CAP_OFFSET_BYTES_SHIFT 4
#define ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF_LBN 67
#define ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF_WIDTH 29
#define ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT 4
#define ESF_GZ_CFGBAR_CONT_CAP_OFF_LO_LBN 68
#define ESF_GZ_CFGBAR_CONT_CAP_OFF_LO_WIDTH 28
#define ESF_GZ_CFGBAR_CONT_CAP_RSV_LBN 67
#define ESF_GZ_CFGBAR_CONT_CAP_RSV_WIDTH 1
#define ESF_GZ_CFGBAR_EF100_BAR_LBN 64
#define ESF_GZ_CFGBAR_EF100_BAR_WIDTH 3
#define ESE_GZ_CFGBAR_EF100_BAR_NUM_INVALID 7
#define ESE_GZ_CFGBAR_EF100_BAR_NUM_EXPANSION_ROM 6
#define ESF_GZ_CFGBAR_CONT_CAP_BAR_LBN 64
#define ESF_GZ_CFGBAR_CONT_CAP_BAR_WIDTH 3
#define ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_INVALID 7
#define ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_EXPANSION_ROM 6
#define ESF_GZ_CFGBAR_ENTRY_SIZE_LBN 32
#define ESF_GZ_CFGBAR_ENTRY_SIZE_WIDTH 32
#define ESE_GZ_CFGBAR_ENTRY_SIZE_EF100 12
#define ESE_GZ_CFGBAR_ENTRY_HEADER_SIZE 8
#define ESF_GZ_CFGBAR_ENTRY_LAST_LBN 28
#define ESF_GZ_CFGBAR_ENTRY_LAST_WIDTH 1
#define ESF_GZ_CFGBAR_ENTRY_REV_LBN 20
#define ESF_GZ_CFGBAR_ENTRY_REV_WIDTH 8
#define ESE_GZ_CFGBAR_ENTRY_REV_EF100 0
#define ESF_GZ_CFGBAR_ENTRY_FORMAT_LBN 0
#define ESF_GZ_CFGBAR_ENTRY_FORMAT_WIDTH 20
#define ESE_GZ_CFGBAR_ENTRY_LAST 0xfffff
#define ESE_GZ_CFGBAR_ENTRY_CONT_CAP_ADDR 0xffffe
#define ESE_GZ_CFGBAR_ENTRY_EF100 0xef100
#define ESE_GZ_XIL_CFGBAR_TBL_ENTRY_STRUCT_SIZE 128
/* XIL_CFGBAR_VSEC */
#define ESF_GZ_VSEC_TBL_OFF_HI_LBN 64
#define ESF_GZ_VSEC_TBL_OFF_HI_WIDTH 32
#define ESE_GZ_VSEC_TBL_OFF_HI_BYTES_SHIFT 32
#define ESF_GZ_VSEC_TBL_OFF_LO_LBN 36
#define ESF_GZ_VSEC_TBL_OFF_LO_WIDTH 28
#define ESE_GZ_VSEC_TBL_OFF_LO_BYTES_SHIFT 4
#define ESF_GZ_VSEC_TBL_BAR_LBN 32
#define ESF_GZ_VSEC_TBL_BAR_WIDTH 4
#define ESE_GZ_VSEC_BAR_NUM_INVALID 7
#define ESE_GZ_VSEC_BAR_NUM_EXPANSION_ROM 6
#define ESF_GZ_VSEC_LEN_LBN 20
#define ESF_GZ_VSEC_LEN_WIDTH 12
#define ESE_GZ_VSEC_LEN_HIGH_OFFT 16
#define ESE_GZ_VSEC_LEN_MIN 12
#define ESF_GZ_VSEC_VER_LBN 16
#define ESF_GZ_VSEC_VER_WIDTH 4
#define ESE_GZ_VSEC_VER_XIL_CFGBAR 0
#define ESF_GZ_VSEC_ID_LBN 0
#define ESF_GZ_VSEC_ID_WIDTH 16
#define ESE_GZ_XILINX_VSEC_ID 0x20
#define ESE_GZ_XIL_CFGBAR_VSEC_STRUCT_SIZE 96
/* rh_egres_hclass */
#define ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L4_CSUM_LBN 15
#define ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L4_CSUM_WIDTH 1
#define ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L3_CLASS_LBN 13
#define ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L3_CLASS_WIDTH 2
#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CSUM_LBN 12
#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CSUM_WIDTH 1
#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CLASS_LBN 10
#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CLASS_WIDTH 2
#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_LBN 8
#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_WIDTH 2
#define ESF_GZ_RX_PREFIX_HCLASS_TUNNEL_CLASS_LBN 5
#define ESF_GZ_RX_PREFIX_HCLASS_TUNNEL_CLASS_WIDTH 3
#define ESF_GZ_RX_PREFIX_HCLASS_L2_N_VLAN_LBN 3
#define ESF_GZ_RX_PREFIX_HCLASS_L2_N_VLAN_WIDTH 2
#define ESF_GZ_RX_PREFIX_HCLASS_L2_CLASS_LBN 2
#define ESF_GZ_RX_PREFIX_HCLASS_L2_CLASS_WIDTH 1
#define ESF_GZ_RX_PREFIX_HCLASS_L2_STATUS_LBN 0
#define ESF_GZ_RX_PREFIX_HCLASS_L2_STATUS_WIDTH 2
#define ESE_GZ_RH_EGRES_HCLASS_STRUCT_SIZE 16
/* sf_driver */
#define ESF_GZ_DRIVER_E_TYPE_LBN 60
#define ESF_GZ_DRIVER_E_TYPE_WIDTH 4
#define ESF_GZ_DRIVER_PHASE_LBN 59
#define ESF_GZ_DRIVER_PHASE_WIDTH 1
#define ESF_GZ_DRIVER_DATA_LBN 0
#define ESF_GZ_DRIVER_DATA_WIDTH 59
#define ESE_GZ_SF_DRIVER_STRUCT_SIZE 64
/* sf_ev_rsvd */
#define ESF_GZ_EV_RSVD_TBD_NEXT_LBN 34
#define ESF_GZ_EV_RSVD_TBD_NEXT_WIDTH 3
#define ESF_GZ_EV_RSVD_EVENT_GEN_FLAGS_LBN 30
#define ESF_GZ_EV_RSVD_EVENT_GEN_FLAGS_WIDTH 4
#define ESF_GZ_EV_RSVD_SRC_QID_LBN 18
#define ESF_GZ_EV_RSVD_SRC_QID_WIDTH 12
#define ESF_GZ_EV_RSVD_SEQ_NUM_LBN 2
#define ESF_GZ_EV_RSVD_SEQ_NUM_WIDTH 16
#define ESF_GZ_EV_RSVD_TBD_LBN 0
#define ESF_GZ_EV_RSVD_TBD_WIDTH 2
#define ESE_GZ_SF_EV_RSVD_STRUCT_SIZE 37
/* sf_flush_evnt */
#define ESF_GZ_EV_FLSH_E_TYPE_LBN 60
#define ESF_GZ_EV_FLSH_E_TYPE_WIDTH 4
#define ESF_GZ_EV_FLSH_PHASE_LBN 59
#define ESF_GZ_EV_FLSH_PHASE_WIDTH 1
#define ESF_GZ_EV_FLSH_SUB_TYPE_LBN 53
#define ESF_GZ_EV_FLSH_SUB_TYPE_WIDTH 6
#define ESF_GZ_EV_FLSH_RSVD_LBN 10
#define ESF_GZ_EV_FLSH_RSVD_WIDTH 43
#define ESF_GZ_EV_FLSH_LABEL_LBN 4
#define ESF_GZ_EV_FLSH_LABEL_WIDTH 6
#define ESF_GZ_EV_FLSH_FLUSH_TYPE_LBN 0
#define ESF_GZ_EV_FLSH_FLUSH_TYPE_WIDTH 4
#define ESE_GZ_SF_FLUSH_EVNT_STRUCT_SIZE 64
/* sf_rx_pkts */
#define ESF_GZ_EV_RXPKTS_E_TYPE_LBN 60
#define ESF_GZ_EV_RXPKTS_E_TYPE_WIDTH 4
#define ESF_GZ_EV_RXPKTS_PHASE_LBN 59
#define ESF_GZ_EV_RXPKTS_PHASE_WIDTH 1
#define ESF_GZ_EV_RXPKTS_RSVD_LBN 22
#define ESF_GZ_EV_RXPKTS_RSVD_WIDTH 37
#define ESF_GZ_EV_RXPKTS_Q_LABEL_LBN 16
#define ESF_GZ_EV_RXPKTS_Q_LABEL_WIDTH 6
#define ESF_GZ_EV_RXPKTS_NUM_PKT_LBN 0
#define ESF_GZ_EV_RXPKTS_NUM_PKT_WIDTH 16
#define ESE_GZ_SF_RX_PKTS_STRUCT_SIZE 64
/* sf_rx_prefix */
#define ESF_GZ_RX_PREFIX_VLAN_STRIP_TCI_LBN 160
#define ESF_GZ_RX_PREFIX_VLAN_STRIP_TCI_WIDTH 16
#define ESF_GZ_RX_PREFIX_CSUM_FRAME_LBN 144
#define ESF_GZ_RX_PREFIX_CSUM_FRAME_WIDTH 16
#define ESF_GZ_RX_PREFIX_INGRESS_VPORT_LBN 128
#define ESF_GZ_RX_PREFIX_INGRESS_VPORT_WIDTH 16
#define ESF_GZ_RX_PREFIX_USER_MARK_LBN 96
#define ESF_GZ_RX_PREFIX_USER_MARK_WIDTH 32
#define ESF_GZ_RX_PREFIX_RSS_HASH_LBN 64
#define ESF_GZ_RX_PREFIX_RSS_HASH_WIDTH 32
#define ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN 32
#define ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_WIDTH 32
#define ESF_GZ_RX_PREFIX_CLASS_LBN 16
#define ESF_GZ_RX_PREFIX_CLASS_WIDTH 16
#define ESF_GZ_RX_PREFIX_USER_FLAG_LBN 15
#define ESF_GZ_RX_PREFIX_USER_FLAG_WIDTH 1
#define ESF_GZ_RX_PREFIX_RSS_HASH_VALID_LBN 14
#define ESF_GZ_RX_PREFIX_RSS_HASH_VALID_WIDTH 1
#define ESF_GZ_RX_PREFIX_LENGTH_LBN 0
#define ESF_GZ_RX_PREFIX_LENGTH_WIDTH 14
#define ESE_GZ_SF_RX_PREFIX_STRUCT_SIZE 176
/* sf_rxtx_generic */
#define ESF_GZ_EV_BARRIER_LBN 167
#define ESF_GZ_EV_BARRIER_WIDTH 1
#define ESF_GZ_EV_RSVD_LBN 130
#define ESF_GZ_EV_RSVD_WIDTH 37
#define ESF_GZ_EV_DPRXY_LBN 129
#define ESF_GZ_EV_DPRXY_WIDTH 1
#define ESF_GZ_EV_VIRTIO_LBN 128
#define ESF_GZ_EV_VIRTIO_WIDTH 1
#define ESF_GZ_EV_COUNT_LBN 0
#define ESF_GZ_EV_COUNT_WIDTH 128
#define ESE_GZ_SF_RXTX_GENERIC_STRUCT_SIZE 168
/* sf_ts_stamp */
#define ESF_GZ_EV_TS_E_TYPE_LBN 60
#define ESF_GZ_EV_TS_E_TYPE_WIDTH 4
#define ESF_GZ_EV_TS_PHASE_LBN 59
#define ESF_GZ_EV_TS_PHASE_WIDTH 1
#define ESF_GZ_EV_TS_RSVD_LBN 56
#define ESF_GZ_EV_TS_RSVD_WIDTH 3
#define ESF_GZ_EV_TS_STATUS_LBN 54
#define ESF_GZ_EV_TS_STATUS_WIDTH 2
#define ESF_GZ_EV_TS_Q_LABEL_LBN 48
#define ESF_GZ_EV_TS_Q_LABEL_WIDTH 6
#define ESF_GZ_EV_TS_DESC_ID_LBN 32
#define ESF_GZ_EV_TS_DESC_ID_WIDTH 16
#define ESF_GZ_EV_TS_PARTIAL_STAMP_LBN 0
#define ESF_GZ_EV_TS_PARTIAL_STAMP_WIDTH 32
#define ESE_GZ_SF_TS_STAMP_STRUCT_SIZE 64
/* sf_tx_cmplt */
#define ESF_GZ_EV_TXCMPL_E_TYPE_LBN 60
#define ESF_GZ_EV_TXCMPL_E_TYPE_WIDTH 4
#define ESF_GZ_EV_TXCMPL_PHASE_LBN 59
#define ESF_GZ_EV_TXCMPL_PHASE_WIDTH 1
#define ESF_GZ_EV_TXCMPL_RSVD_LBN 22
#define ESF_GZ_EV_TXCMPL_RSVD_WIDTH 37
#define ESF_GZ_EV_TXCMPL_Q_LABEL_LBN 16
#define ESF_GZ_EV_TXCMPL_Q_LABEL_WIDTH 6
#define ESF_GZ_EV_TXCMPL_NUM_DESC_LBN 0
#define ESF_GZ_EV_TXCMPL_NUM_DESC_WIDTH 16
#define ESE_GZ_SF_TX_CMPLT_STRUCT_SIZE 64
/* sf_tx_desc2cmpt_dsc_fmt */
#define ESF_GZ_D2C_TGT_VI_ID_LBN 108
#define ESF_GZ_D2C_TGT_VI_ID_WIDTH 16
#define ESF_GZ_D2C_CMPT2_LBN 107
#define ESF_GZ_D2C_CMPT2_WIDTH 1
#define ESF_GZ_D2C_ABS_VI_ID_LBN 106
#define ESF_GZ_D2C_ABS_VI_ID_WIDTH 1
#define ESF_GZ_D2C_ORDERED_LBN 105
#define ESF_GZ_D2C_ORDERED_WIDTH 1
#define ESF_GZ_D2C_SKIP_N_LBN 97
#define ESF_GZ_D2C_SKIP_N_WIDTH 8
#define ESF_GZ_D2C_RSVD_LBN 64
#define ESF_GZ_D2C_RSVD_WIDTH 33
#define ESF_GZ_D2C_COMPLETION_LBN 0
#define ESF_GZ_D2C_COMPLETION_WIDTH 64
#define ESE_GZ_SF_TX_DESC2CMPT_DSC_FMT_STRUCT_SIZE 124
/* sf_tx_mem2mem_dsc_fmt */
#define ESF_GZ_M2M_ADDR_SPC_EN_LBN 123
#define ESF_GZ_M2M_ADDR_SPC_EN_WIDTH 1
#define ESF_GZ_M2M_TRANSLATE_ADDR_LBN 122
#define ESF_GZ_M2M_TRANSLATE_ADDR_WIDTH 1
#define ESF_GZ_M2M_RSVD_LBN 120
#define ESF_GZ_M2M_RSVD_WIDTH 2
#define ESF_GZ_M2M_ADDR_SPC_LBN 108
#define ESF_GZ_M2M_ADDR_SPC_WIDTH 12
#define ESF_GZ_M2M_ADDR_SPC_PASID_LBN 86
#define ESF_GZ_M2M_ADDR_SPC_PASID_WIDTH 22
#define ESF_GZ_M2M_ADDR_SPC_MODE_LBN 84
#define ESF_GZ_M2M_ADDR_SPC_MODE_WIDTH 2
#define ESF_GZ_M2M_LEN_MINUS_1_LBN 64
#define ESF_GZ_M2M_LEN_MINUS_1_WIDTH 20
#define ESF_GZ_M2M_ADDR_LBN 0
#define ESF_GZ_M2M_ADDR_WIDTH 64
#define ESE_GZ_SF_TX_MEM2MEM_DSC_FMT_STRUCT_SIZE 124
/* sf_tx_ovr_dsc_fmt */
#define ESF_GZ_TX_PREFIX_MARK_EN_LBN 123
#define ESF_GZ_TX_PREFIX_MARK_EN_WIDTH 1
#define ESF_GZ_TX_PREFIX_INGRESS_MPORT_EN_LBN 122
#define ESF_GZ_TX_PREFIX_INGRESS_MPORT_EN_WIDTH 1
#define ESF_GZ_TX_PREFIX_INLINE_CAPSULE_META_LBN 121
#define ESF_GZ_TX_PREFIX_INLINE_CAPSULE_META_WIDTH 1
#define ESF_GZ_TX_PREFIX_EGRESS_MPORT_EN_LBN 120
#define ESF_GZ_TX_PREFIX_EGRESS_MPORT_EN_WIDTH 1
#define ESF_GZ_TX_PREFIX_RSRVD_LBN 64
#define ESF_GZ_TX_PREFIX_RSRVD_WIDTH 56
#define ESF_GZ_TX_PREFIX_EGRESS_MPORT_LBN 48
#define ESF_GZ_TX_PREFIX_EGRESS_MPORT_WIDTH 16
#define ESF_GZ_TX_PREFIX_INGRESS_MPORT_LBN 32
#define ESF_GZ_TX_PREFIX_INGRESS_MPORT_WIDTH 16
#define ESF_GZ_TX_PREFIX_MARK_LBN 0
#define ESF_GZ_TX_PREFIX_MARK_WIDTH 32
#define ESE_GZ_SF_TX_OVR_DSC_FMT_STRUCT_SIZE 124
/* sf_tx_seg_dsc_fmt */
#define ESF_GZ_TX_SEG_ADDR_SPC_EN_LBN 123
#define ESF_GZ_TX_SEG_ADDR_SPC_EN_WIDTH 1
#define ESF_GZ_TX_SEG_TRANSLATE_ADDR_LBN 122
#define ESF_GZ_TX_SEG_TRANSLATE_ADDR_WIDTH 1
#define ESF_GZ_TX_SEG_RSVD2_LBN 120
#define ESF_GZ_TX_SEG_RSVD2_WIDTH 2
#define ESF_GZ_TX_SEG_ADDR_SPC_LBN 108
#define ESF_GZ_TX_SEG_ADDR_SPC_WIDTH 12
#define ESF_GZ_TX_SEG_ADDR_SPC_PASID_LBN 86
#define ESF_GZ_TX_SEG_ADDR_SPC_PASID_WIDTH 22
#define ESF_GZ_TX_SEG_ADDR_SPC_MODE_LBN 84
#define ESF_GZ_TX_SEG_ADDR_SPC_MODE_WIDTH 2
#define ESF_GZ_TX_SEG_RSVD_LBN 80
#define ESF_GZ_TX_SEG_RSVD_WIDTH 4
#define ESF_GZ_TX_SEG_LEN_LBN 64
#define ESF_GZ_TX_SEG_LEN_WIDTH 16
#define ESF_GZ_TX_SEG_ADDR_LBN 0
#define ESF_GZ_TX_SEG_ADDR_WIDTH 64
#define ESE_GZ_SF_TX_SEG_DSC_FMT_STRUCT_SIZE 124
/* sf_tx_std_dsc_fmt */
#define ESF_GZ_TX_SEND_VLAN_INSERT_TCI_LBN 108
#define ESF_GZ_TX_SEND_VLAN_INSERT_TCI_WIDTH 16
#define ESF_GZ_TX_SEND_VLAN_INSERT_EN_LBN 107
#define ESF_GZ_TX_SEND_VLAN_INSERT_EN_WIDTH 1
#define ESF_GZ_TX_SEND_TSTAMP_REQ_LBN 106
#define ESF_GZ_TX_SEND_TSTAMP_REQ_WIDTH 1
#define ESF_GZ_TX_SEND_CSO_OUTER_L4_LBN 105
#define ESF_GZ_TX_SEND_CSO_OUTER_L4_WIDTH 1
#define ESF_GZ_TX_SEND_CSO_OUTER_L3_LBN 104
#define ESF_GZ_TX_SEND_CSO_OUTER_L3_WIDTH 1
#define ESF_GZ_TX_SEND_CSO_INNER_L3_LBN 101
#define ESF_GZ_TX_SEND_CSO_INNER_L3_WIDTH 3
#define ESF_GZ_TX_SEND_RSVD_LBN 99
#define ESF_GZ_TX_SEND_RSVD_WIDTH 2
#define ESF_GZ_TX_SEND_CSO_PARTIAL_EN_LBN 97
#define ESF_GZ_TX_SEND_CSO_PARTIAL_EN_WIDTH 2
#define ESF_GZ_TX_SEND_CSO_PARTIAL_CSUM_W_LBN 92
#define ESF_GZ_TX_SEND_CSO_PARTIAL_CSUM_W_WIDTH 5
#define ESF_GZ_TX_SEND_CSO_PARTIAL_START_W_LBN 83
#define ESF_GZ_TX_SEND_CSO_PARTIAL_START_W_WIDTH 9
#define ESF_GZ_TX_SEND_NUM_SEGS_LBN 78
#define ESF_GZ_TX_SEND_NUM_SEGS_WIDTH 5
#define ESF_GZ_TX_SEND_LEN_LBN 64
#define ESF_GZ_TX_SEND_LEN_WIDTH 14
#define ESF_GZ_TX_SEND_ADDR_LBN 0
#define ESF_GZ_TX_SEND_ADDR_WIDTH 64
#define ESE_GZ_SF_TX_STD_DSC_FMT_STRUCT_SIZE 124
/* sf_tx_tso_dsc_fmt */
#define ESF_GZ_TX_TSO_VLAN_INSERT_TCI_LBN 108
#define ESF_GZ_TX_TSO_VLAN_INSERT_TCI_WIDTH 16
#define ESF_GZ_TX_TSO_VLAN_INSERT_EN_LBN 107
#define ESF_GZ_TX_TSO_VLAN_INSERT_EN_WIDTH 1
#define ESF_GZ_TX_TSO_TSTAMP_REQ_LBN 106
#define ESF_GZ_TX_TSO_TSTAMP_REQ_WIDTH 1
#define ESF_GZ_TX_TSO_CSO_OUTER_L4_LBN 105
#define ESF_GZ_TX_TSO_CSO_OUTER_L4_WIDTH 1
#define ESF_GZ_TX_TSO_CSO_OUTER_L3_LBN 104
#define ESF_GZ_TX_TSO_CSO_OUTER_L3_WIDTH 1
#define ESF_GZ_TX_TSO_CSO_INNER_L3_LBN 101
#define ESF_GZ_TX_TSO_CSO_INNER_L3_WIDTH 3
#define ESF_GZ_TX_TSO_RSVD_LBN 94
#define ESF_GZ_TX_TSO_RSVD_WIDTH 7
#define ESF_GZ_TX_TSO_CSO_INNER_L4_LBN 93
#define ESF_GZ_TX_TSO_CSO_INNER_L4_WIDTH 1
#define ESF_GZ_TX_TSO_INNER_L4_OFF_W_LBN 85
#define ESF_GZ_TX_TSO_INNER_L4_OFF_W_WIDTH 8
#define ESF_GZ_TX_TSO_INNER_L3_OFF_W_LBN 77
#define ESF_GZ_TX_TSO_INNER_L3_OFF_W_WIDTH 8
#define ESF_GZ_TX_TSO_OUTER_L4_OFF_W_LBN 69
#define ESF_GZ_TX_TSO_OUTER_L4_OFF_W_WIDTH 8
#define ESF_GZ_TX_TSO_OUTER_L3_OFF_W_LBN 64
#define ESF_GZ_TX_TSO_OUTER_L3_OFF_W_WIDTH 5
#define ESF_GZ_TX_TSO_PAYLOAD_LEN_LBN 42
#define ESF_GZ_TX_TSO_PAYLOAD_LEN_WIDTH 22
#define ESF_GZ_TX_TSO_HDR_LEN_W_LBN 34
#define ESF_GZ_TX_TSO_HDR_LEN_W_WIDTH 8
#define ESF_GZ_TX_TSO_ED_OUTER_UDP_LEN_LBN 33
#define ESF_GZ_TX_TSO_ED_OUTER_UDP_LEN_WIDTH 1
#define ESF_GZ_TX_TSO_ED_INNER_IP_LEN_LBN 32
#define ESF_GZ_TX_TSO_ED_INNER_IP_LEN_WIDTH 1
#define ESF_GZ_TX_TSO_ED_OUTER_IP_LEN_LBN 31
#define ESF_GZ_TX_TSO_ED_OUTER_IP_LEN_WIDTH 1
#define ESF_GZ_TX_TSO_ED_INNER_IP4_ID_LBN 29
#define ESF_GZ_TX_TSO_ED_INNER_IP4_ID_WIDTH 2
#define ESF_GZ_TX_TSO_ED_OUTER_IP4_ID_LBN 27
#define ESF_GZ_TX_TSO_ED_OUTER_IP4_ID_WIDTH 2
#define ESF_GZ_TX_TSO_PAYLOAD_NUM_SEGS_LBN 17
#define ESF_GZ_TX_TSO_PAYLOAD_NUM_SEGS_WIDTH 10
#define ESF_GZ_TX_TSO_HDR_NUM_SEGS_LBN 14
#define ESF_GZ_TX_TSO_HDR_NUM_SEGS_WIDTH 3
#define ESF_GZ_TX_TSO_MSS_LBN 0
#define ESF_GZ_TX_TSO_MSS_WIDTH 14
#define ESE_GZ_SF_TX_TSO_DSC_FMT_STRUCT_SIZE 124
/* Enum DESIGN_PARAMS */
#define ESE_EF100_DP_GZ_RX_MAX_RUNT 17
#define ESE_EF100_DP_GZ_VI_STRIDES 16
#define ESE_EF100_DP_GZ_NMMU_PAGE_SIZES 15
#define ESE_EF100_DP_GZ_EVQ_TIMER_TICK_NANOS 14
#define ESE_EF100_DP_GZ_MEM2MEM_MAX_LEN 13
#define ESE_EF100_DP_GZ_COMPAT 12
#define ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES 11
#define ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS 10
#define ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN 9
#define ESE_EF100_DP_GZ_TXQ_SIZE_GRANULARITY 8
#define ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY 7
#define ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS 6
#define ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN 5
#define ESE_EF100_DP_GZ_RX_L4_CSUM_PROTOCOLS 4
#define ESE_EF100_DP_GZ_NMMU_GROUP_SIZE 3
#define ESE_EF100_DP_GZ_EVQ_UNSOL_CREDIT_SEQ_BITS 2
#define ESE_EF100_DP_GZ_PARTIAL_TSTAMP_SUB_NANO_BITS 1
#define ESE_EF100_DP_GZ_PAD 0
/* Enum DESIGN_PARAM_DEFAULTS */
#define ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN_DEFAULT 0x3fffff
#define ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES_DEFAULT 8192
#define ESE_EF100_DP_GZ_MEM2MEM_MAX_LEN_DEFAULT 8192
#define ESE_EF100_DP_GZ_RX_L4_CSUM_PROTOCOLS_DEFAULT 0x1106
#define ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS_DEFAULT 0x3ff
#define ESE_EF100_DP_GZ_RX_MAX_RUNT_DEFAULT 640
#define ESE_EF100_DP_GZ_EVQ_TIMER_TICK_NANOS_DEFAULT 512
#define ESE_EF100_DP_GZ_NMMU_PAGE_SIZES_DEFAULT 512
#define ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT 192
#define ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY_DEFAULT 64
#define ESE_EF100_DP_GZ_TXQ_SIZE_GRANULARITY_DEFAULT 64
#define ESE_EF100_DP_GZ_NMMU_GROUP_SIZE_DEFAULT 32
#define ESE_EF100_DP_GZ_VI_STRIDES_DEFAULT 16
#define ESE_EF100_DP_GZ_EVQ_UNSOL_CREDIT_SEQ_BITS_DEFAULT 7
#define ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT 4
#define ESE_EF100_DP_GZ_PARTIAL_TSTAMP_SUB_NANO_BITS_DEFAULT 2
#define ESE_EF100_DP_GZ_COMPAT_DEFAULT 0
/* Enum HOST_IF_CONSTANTS */
#define ESE_GZ_FCW_LEN 0x4C
#define ESE_GZ_RX_PKT_PREFIX_LEN 22
/* Enum PCI_CONSTANTS */
#define ESE_GZ_PCI_BASE_CONFIG_SPACE_SIZE 256
#define ESE_GZ_PCI_EXPRESS_XCAP_HDR_SIZE 4
/* Enum RH_HCLASS_L2_CLASS */
#define ESE_GZ_RH_HCLASS_L2_CLASS_E2_0123VLAN 1
#define ESE_GZ_RH_HCLASS_L2_CLASS_OTHER 0
/* Enum RH_HCLASS_L2_STATUS */
#define ESE_GZ_RH_HCLASS_L2_STATUS_RESERVED 3
#define ESE_GZ_RH_HCLASS_L2_STATUS_FCS_ERR 2
#define ESE_GZ_RH_HCLASS_L2_STATUS_LEN_ERR 1
#define ESE_GZ_RH_HCLASS_L2_STATUS_OK 0
/* Enum RH_HCLASS_L3_CLASS */
#define ESE_GZ_RH_HCLASS_L3_CLASS_OTHER 3
#define ESE_GZ_RH_HCLASS_L3_CLASS_IP6 2
#define ESE_GZ_RH_HCLASS_L3_CLASS_IP4BAD 1
#define ESE_GZ_RH_HCLASS_L3_CLASS_IP4GOOD 0
/* Enum RH_HCLASS_L4_CLASS */
#define ESE_GZ_RH_HCLASS_L4_CLASS_OTHER 3
#define ESE_GZ_RH_HCLASS_L4_CLASS_FRAG 2
#define ESE_GZ_RH_HCLASS_L4_CLASS_UDP 1
#define ESE_GZ_RH_HCLASS_L4_CLASS_TCP 0
/* Enum RH_HCLASS_L4_CSUM */
#define ESE_GZ_RH_HCLASS_L4_CSUM_GOOD 1
#define ESE_GZ_RH_HCLASS_L4_CSUM_BAD_OR_UNKNOWN 0
/* Enum RH_HCLASS_TUNNEL_CLASS */
#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_7 7
#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_6 6
#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_5 5
#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_4 4
#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_GENEVE 3
#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_NVGRE 2
#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_VXLAN 1
#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_NONE 0
/* Enum TX_DESC_CSO_PARTIAL_EN */
#define ESE_GZ_TX_DESC_CSO_PARTIAL_EN_TCP 2
#define ESE_GZ_TX_DESC_CSO_PARTIAL_EN_UDP 1
#define ESE_GZ_TX_DESC_CSO_PARTIAL_EN_OFF 0
/* Enum TX_DESC_CS_INNER_L3 */
#define ESE_GZ_TX_DESC_CS_INNER_L3_GENEVE 3
#define ESE_GZ_TX_DESC_CS_INNER_L3_NVGRE 2
#define ESE_GZ_TX_DESC_CS_INNER_L3_VXLAN 1
#define ESE_GZ_TX_DESC_CS_INNER_L3_OFF 0
/* Enum TX_DESC_IP4_ID */
#define ESE_GZ_TX_DESC_IP4_ID_INC_MOD16 2
#define ESE_GZ_TX_DESC_IP4_ID_INC_MOD15 1
#define ESE_GZ_TX_DESC_IP4_ID_NO_OP 0
/**************************************************************************/
#define ESF_GZ_EV_DEBUG_EVENT_GEN_FLAGS_LBN 44
#define ESF_GZ_EV_DEBUG_EVENT_GEN_FLAGS_WIDTH 4
#define ESF_GZ_EV_DEBUG_SRC_QID_LBN 32
#define ESF_GZ_EV_DEBUG_SRC_QID_WIDTH 12
#define ESF_GZ_EV_DEBUG_SEQ_NUM_LBN 16
#define ESF_GZ_EV_DEBUG_SEQ_NUM_WIDTH 16
#endif /* EFX_EF100_REGS_H */
// SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2005-2019 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include "net_driver.h"
#include "ef100_rx.h"
#include "rx_common.h"
#include "efx.h"
/* RX stubs */
void ef100_rx_write(struct efx_rx_queue *rx_queue)
{
}
void __ef100_rx_packet(struct efx_channel *channel)
{
/* Stub. No RX path yet. Discard the buffer. */
struct efx_rx_buffer *rx_buf = efx_rx_buffer(&channel->rx_queue,
channel->rx_pkt_index);
struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
efx_free_rx_buffers(rx_queue, rx_buf, 1);
channel->rx_pkt_n_frags = 0;
}
/* SPDX-License-Identifier: GPL-2.0-only */
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2019 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_EF100_RX_H
#define EFX_EF100_RX_H
#include "net_driver.h"
void ef100_rx_write(struct efx_rx_queue *rx_queue);
void __ef100_rx_packet(struct efx_channel *channel);
#endif
// SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2018 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include "net_driver.h"
#include "tx_common.h"
#include "nic_common.h"
#include "ef100_tx.h"
/* TX queue stubs */
int ef100_tx_probe(struct efx_tx_queue *tx_queue)
{
return 0;
}
void ef100_tx_init(struct efx_tx_queue *tx_queue)
{
/* must be the inverse of lookup in efx_get_tx_channel */
tx_queue->core_txq =
netdev_get_tx_queue(tx_queue->efx->net_dev,
tx_queue->channel->channel -
tx_queue->efx->tx_channel_offset);
}
void ef100_tx_write(struct efx_tx_queue *tx_queue)
{
}
/* Add a socket buffer to a TX queue
*
* You must hold netif_tx_lock() to call this function.
*
* Returns 0 on success, error code otherwise. In case of an error this
* function will free the SKB.
*/
int ef100_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
{
/* Stub. No TX path yet. */
struct efx_nic *efx = tx_queue->efx;
netif_stop_queue(efx->net_dev);
dev_kfree_skb_any(skb);
return -ENODEV;
}
/* SPDX-License-Identifier: GPL-2.0-only */
/****************************************************************************
* Driver for Solarflare network controllers and boards
* Copyright 2019 Solarflare Communications Inc.
* Copyright 2019-2020 Xilinx Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_EF100_TX_H
#define EFX_EF100_TX_H
#include "net_driver.h"
int ef100_tx_probe(struct efx_tx_queue *tx_queue);
void ef100_tx_init(struct efx_tx_queue *tx_queue);
void ef100_tx_write(struct efx_tx_queue *tx_queue);
netdev_tx_t ef100_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
#endif
......@@ -25,6 +25,7 @@
#include "efx.h"
#include "efx_common.h"
#include "efx_channels.h"
#include "ef100.h"
#include "rx_common.h"
#include "tx_common.h"
#include "nic.h"
......@@ -1360,8 +1361,14 @@ static int __init efx_init_module(void)
if (rc < 0)
goto err_pci;
rc = pci_register_driver(&ef100_pci_driver);
if (rc < 0)
goto err_pci_ef100;
return 0;
err_pci_ef100:
pci_unregister_driver(&efx_pci_driver);
err_pci:
efx_destroy_reset_workqueue();
err_reset:
......@@ -1378,6 +1385,7 @@ static void __exit efx_exit_module(void)
{
printk(KERN_INFO "Solarflare NET driver unloading\n");
pci_unregister_driver(&ef100_pci_driver);
pci_unregister_driver(&efx_pci_driver);
efx_destroy_reset_workqueue();
#ifdef CONFIG_SFC_SRIOV
......
......@@ -8,7 +8,10 @@
#ifndef EFX_EFX_H
#define EFX_EFX_H
#include <linux/indirect_call_wrapper.h>
#include "net_driver.h"
#include "ef100_rx.h"
#include "ef100_tx.h"
#include "filter.h"
int efx_net_open(struct net_device *net_dev);
......@@ -18,13 +21,18 @@ int efx_net_stop(struct net_device *net_dev);
void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue);
netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
struct net_device *net_dev);
netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
netdev_tx_t __efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
static inline netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
{
return INDIRECT_CALL_2(tx_queue->efx->type->tx_enqueue,
ef100_enqueue_skb, __efx_enqueue_skb,
tx_queue, skb);
}
void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
void efx_xmit_done_single(struct efx_tx_queue *tx_queue);
int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
void *type_data);
extern unsigned int efx_piobuf_size;
extern bool efx_separate_tx_channels;
/* RX */
void __efx_rx_packet(struct efx_channel *channel);
......@@ -33,7 +41,9 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
static inline void efx_rx_flush_packet(struct efx_channel *channel)
{
if (channel->rx_pkt_n_frags)
__efx_rx_packet(channel);
INDIRECT_CALL_2(channel->efx->type->rx_packet,
__ef100_rx_packet, __efx_rx_packet,
channel);
}
/* Maximum number of TCP segments we support for soft-TSO */
......
......@@ -814,14 +814,18 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
*/
int efx_reset(struct efx_nic *efx, enum reset_type method)
{
int rc, rc2 = 0;
bool disabled;
int rc, rc2;
netif_info(efx, drv, efx->net_dev, "resetting (%s)\n",
RESET_TYPE(method));
efx_device_detach_sync(efx);
efx_reset_down(efx, method);
/* efx_reset_down() grabs locks that prevent recovery on EF100.
* EF100 reset is handled in the efx_nic_type callback below.
*/
if (efx_nic_rev(efx) != EFX_REV_EF100)
efx_reset_down(efx, method);
rc = efx->type->reset(efx, method);
if (rc) {
......@@ -849,7 +853,8 @@ int efx_reset(struct efx_nic *efx, enum reset_type method)
disabled = rc ||
method == RESET_TYPE_DISABLE ||
method == RESET_TYPE_RECOVER_OR_DISABLE;
rc2 = efx_reset_up(efx, method, !disabled);
if (efx_nic_rev(efx) != EFX_REV_EF100)
rc2 = efx_reset_up(efx, method, !disabled);
if (rc2) {
disabled = true;
if (!rc)
......
......@@ -221,8 +221,6 @@ static int efx_ethtool_get_ts_info(struct net_device *net_dev,
return 0;
}
const char *efx_driver_name = KBUILD_MODNAME;
const struct ethtool_ops efx_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_USECS_IRQ |
......@@ -232,7 +230,6 @@ const struct ethtool_ops efx_ethtool_ops = {
.get_regs = efx_ethtool_get_regs,
.get_msglevel = efx_ethtool_get_msglevel,
.set_msglevel = efx_ethtool_set_msglevel,
.nway_reset = efx_ethtool_nway_reset,
.get_link = ethtool_op_get_link,
.get_coalesce = efx_ethtool_get_coalesce,
.set_coalesce = efx_ethtool_set_coalesce,
......
......@@ -104,7 +104,7 @@ void efx_ethtool_get_drvinfo(struct net_device *net_dev,
{
struct efx_nic *efx = netdev_priv(net_dev);
strlcpy(info->driver, efx_driver_name, sizeof(info->driver));
strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
strlcpy(info->version, EFX_DRIVER_VERSION, sizeof(info->version));
efx_mcdi_print_fwver(efx, info->fw_version,
sizeof(info->fw_version));
......@@ -173,14 +173,6 @@ void efx_ethtool_self_test(struct net_device *net_dev,
test->flags |= ETH_TEST_FL_FAILED;
}
/* Restart autonegotiation */
int efx_ethtool_nway_reset(struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
return mdio45_nway_restart(&efx->mdio);
}
void efx_ethtool_get_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause)
{
......
......@@ -11,15 +11,12 @@
#ifndef EFX_ETHTOOL_COMMON_H
#define EFX_ETHTOOL_COMMON_H
extern const char *efx_driver_name;
void efx_ethtool_get_drvinfo(struct net_device *net_dev,
struct ethtool_drvinfo *info);
u32 efx_ethtool_get_msglevel(struct net_device *net_dev);
void efx_ethtool_set_msglevel(struct net_device *net_dev, u32 msg_enable);
void efx_ethtool_self_test(struct net_device *net_dev,
struct ethtool_test *test, u64 *data);
int efx_ethtool_nway_reset(struct net_device *net_dev);
void efx_ethtool_get_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause);
int efx_ethtool_set_pauseparam(struct net_device *net_dev,
......
......@@ -75,6 +75,11 @@
#endif
#endif
static inline u32 efx_reg(struct efx_nic *efx, unsigned int reg)
{
return efx->reg_base + reg;
}
#ifdef EFX_USE_QWORD_IO
static inline void _efx_writeq(struct efx_nic *efx, __le64 value,
unsigned int reg)
......@@ -217,8 +222,11 @@ static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value,
efx_reado(efx, value, reg + index * sizeof(efx_oword_t));
}
/* default VI stride (step between per-VI registers) is 8K */
#define EFX_DEFAULT_VI_STRIDE 0x2000
/* default VI stride (step between per-VI registers) is 8K on EF10 and
* 64K on EF100
*/
#define EFX_DEFAULT_VI_STRIDE 0x2000
#define EF100_DEFAULT_VI_STRIDE 0x10000
/* Calculate offset to page-mapped register */
static inline unsigned int efx_paged_reg(struct efx_nic *efx, unsigned int page,
......@@ -265,7 +273,9 @@ _efx_writed_page(struct efx_nic *efx, const efx_dword_t *value,
#define efx_writed_page(efx, value, reg, page) \
_efx_writed_page(efx, value, \
reg + \
BUILD_BUG_ON_ZERO((reg) != 0x400 && \
BUILD_BUG_ON_ZERO((reg) != 0x180 && \
(reg) != 0x200 && \
(reg) != 0x400 && \
(reg) != 0x420 && \
(reg) != 0x830 && \
(reg) != 0x83c && \
......
......@@ -1337,7 +1337,7 @@ void efx_mcdi_process_event(struct efx_channel *channel,
efx_mcdi_process_link_change(efx, event);
break;
case MCDI_EVENT_CODE_SENSOREVT:
efx_mcdi_sensor_event(efx, event);
efx_sensor_event(efx, event);
break;
case MCDI_EVENT_CODE_SCHEDERR:
netif_dbg(efx, hw, efx->net_dev,
......
......@@ -327,10 +327,10 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field)
#define MCDI_CAPABILITY(field) \
MC_CMD_GET_CAPABILITIES_V4_OUT_ ## field ## _LBN
MC_CMD_GET_CAPABILITIES_V8_OUT_ ## field ## _LBN
#define MCDI_CAPABILITY_OFST(field) \
MC_CMD_GET_CAPABILITIES_V4_OUT_ ## field ## _OFST
MC_CMD_GET_CAPABILITIES_V8_OUT_ ## field ## _OFST
#define efx_has_cap(efx, field) \
efx->type->check_caps(efx, \
......
......@@ -963,7 +963,9 @@ struct efx_async_filter_insertion {
* @vpd_sn: Serial number read from VPD
* @xdp_rxq_info_failed: Have any of the rx queues failed to initialise their
* xdp_rxq_info structures?
* @netdev_notifier: Netdevice notifier.
* @mem_bar: The BAR that is mapped into membase.
* @reg_base: Offset from the start of the bar to the function control window.
* @monitor_work: Hardware monitor workitem
* @biu_lock: BIU (bus interface unit) lock
* @last_irq_cpu: Last CPU to handle a possible test interrupt. This
......@@ -1141,7 +1143,10 @@ struct efx_nic {
char *vpd_sn;
bool xdp_rxq_info_failed;
struct notifier_block netdev_notifier;
unsigned int mem_bar;
u32 reg_base;
/* The following fields may be written more often */
......@@ -1244,6 +1249,7 @@ struct efx_udp_tunnel {
* @tx_init: Initialise TX queue on the NIC
* @tx_remove: Free resources for TX queue
* @tx_write: Write TX descriptors and doorbell
* @tx_enqueue: Add an SKB to TX queue
* @rx_push_rss_config: Write RSS hash key and indirection table to the NIC
* @rx_pull_rss_config: Read RSS hash key and indirection table back from the NIC
* @rx_push_rss_context_config: Write RSS hash key and indirection table for
......@@ -1255,6 +1261,7 @@ struct efx_udp_tunnel {
* @rx_remove: Free resources for RX queue
* @rx_write: Write RX descriptors and doorbell
* @rx_defer_refill: Generate a refill reminder event
* @rx_packet: Receive the queued RX buffer on a channel
* @ev_probe: Allocate resources for event queue
* @ev_init: Initialise event queue on the NIC
* @ev_fini: Deinitialise event queue on the NIC
......@@ -1299,6 +1306,7 @@ struct efx_udp_tunnel {
* @udp_tnl_push_ports: Push the list of UDP tunnel ports to the NIC if required.
* @udp_tnl_has_port: Check if a port has been added as UDP tunnel
* @print_additional_fwver: Dump NIC-specific additional FW version info
* @sensor_event: Handle a sensor event from MCDI
* @revision: Hardware architecture revision
* @txd_ptr_tbl_base: TX descriptor ring base address
* @rxd_ptr_tbl_base: RX descriptor ring base address
......@@ -1379,6 +1387,7 @@ struct efx_nic_type {
void (*tx_init)(struct efx_tx_queue *tx_queue);
void (*tx_remove)(struct efx_tx_queue *tx_queue);
void (*tx_write)(struct efx_tx_queue *tx_queue);
netdev_tx_t (*tx_enqueue)(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
unsigned int (*tx_limit_len)(struct efx_tx_queue *tx_queue,
dma_addr_t dma_addr, unsigned int len);
int (*rx_push_rss_config)(struct efx_nic *efx, bool user,
......@@ -1396,6 +1405,7 @@ struct efx_nic_type {
void (*rx_remove)(struct efx_rx_queue *rx_queue);
void (*rx_write)(struct efx_rx_queue *rx_queue);
void (*rx_defer_refill)(struct efx_rx_queue *rx_queue);
void (*rx_packet)(struct efx_channel *channel);
int (*ev_probe)(struct efx_channel *channel);
int (*ev_init)(struct efx_channel *channel);
void (*ev_fini)(struct efx_channel *channel);
......@@ -1470,6 +1480,7 @@ struct efx_nic_type {
bool (*udp_tnl_has_port)(struct efx_nic *efx, __be16 port);
size_t (*print_additional_fwver)(struct efx_nic *efx, char *buf,
size_t len);
void (*sensor_event)(struct efx_nic *efx, efx_qword_t *ev);
int revision;
unsigned int txd_ptr_tbl_base;
......@@ -1521,6 +1532,13 @@ efx_get_channel(struct efx_nic *efx, unsigned index)
_channel = _channel->channel ? \
(_efx)->channel[_channel->channel - 1] : NULL)
static inline struct efx_channel *
efx_get_tx_channel(struct efx_nic *efx, unsigned int index)
{
EFX_WARN_ON_ONCE_PARANOID(index >= efx->n_tx_channels);
return efx->channel[efx->tx_channel_offset + index];
}
static inline struct efx_tx_queue *
efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
{
......
......@@ -225,6 +225,12 @@ void efx_nic_event_test_start(struct efx_channel *channel);
bool efx_nic_event_present(struct efx_channel *channel);
static inline void efx_sensor_event(struct efx_nic *efx, efx_qword_t *ev)
{
if (efx->type->sensor_event)
efx->type->sensor_event(efx, ev);
}
/* Some statistics are computed as A - B where A and B each increase
* linearly with some hardware counter(s) and the counters are read
* asynchronously. If the counters contributing to B are always read
......
......@@ -1018,6 +1018,7 @@ const struct efx_nic_type siena_a0_nic_type = {
.tx_remove = efx_farch_tx_remove,
.tx_write = efx_farch_tx_write,
.tx_limit_len = efx_farch_tx_limit_len,
.tx_enqueue = __efx_enqueue_skb,
.rx_push_rss_config = siena_rx_push_rss_config,
.rx_pull_rss_config = siena_rx_pull_rss_config,
.rx_probe = efx_farch_rx_probe,
......@@ -1025,6 +1026,7 @@ const struct efx_nic_type siena_a0_nic_type = {
.rx_remove = efx_farch_rx_remove,
.rx_write = efx_farch_rx_write,
.rx_defer_refill = efx_farch_rx_defer_refill,
.rx_packet = __efx_rx_packet,
.ev_probe = efx_farch_ev_probe,
.ev_init = efx_farch_ev_init,
.ev_fini = efx_farch_ev_fini,
......@@ -1096,4 +1098,5 @@ const struct efx_nic_type siena_a0_nic_type = {
1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT),
.rx_hash_key_size = 16,
.check_caps = siena_check_caps,
.sensor_event = efx_mcdi_sensor_event,
};
......@@ -284,7 +284,7 @@ static int efx_enqueue_skb_pio(struct efx_tx_queue *tx_queue,
* Returns NETDEV_TX_OK.
* You must hold netif_tx_lock() to call this function.
*/
netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
netdev_tx_t __efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
{
unsigned int old_insert_count = tx_queue->insert_count;
bool xmit_more = netdev_xmit_more();
......@@ -503,7 +503,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
}
tx_queue = efx_get_tx_queue(efx, index, type);
return efx_enqueue_skb(tx_queue, skb);
return __efx_enqueue_skb(tx_queue, skb);
}
void efx_xmit_done_single(struct efx_tx_queue *tx_queue)
......
......@@ -40,4 +40,6 @@ int efx_tx_map_data(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
unsigned int efx_tx_max_skb_descs(struct efx_nic *efx);
int efx_tx_tso_fallback(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
extern bool efx_separate_tx_channels;
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment