You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
sfc: skeleton EF100 PF driver
No TX or RX path, no MCDI, not even an ifup/down handler. Besides stubs, the bulk of the patch deals with reading the Xilinx extended PCIe capability, which tells us where to find our BAR. Though in the same module, EF100 has its own struct pci_driver, which is named sfc_ef100. A small number of additional nic_type methods are added; those in the TX (tx_enqueue) and RX (rx_packet) paths are called through indirect call wrappers to minimise the performance impact. Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
61060c5dc5
commit
51b35a454e
@@ -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,
|
||||
};
|
||||
|
||||
541
drivers/net/ethernet/sfc/ef100.c
Normal file
541
drivers/net/ethernet/sfc/ef100.c
Normal file
File diff suppressed because it is too large
Load Diff
12
drivers/net/ethernet/sfc/ef100.h
Normal file
12
drivers/net/ethernet/sfc/ef100.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/* 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;
|
||||
24
drivers/net/ethernet/sfc/ef100_ethtool.c
Normal file
24
drivers/net/ethernet/sfc/ef100_ethtool.c
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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,
|
||||
};
|
||||
12
drivers/net/ethernet/sfc/ef100_ethtool.h
Normal file
12
drivers/net/ethernet/sfc/ef100_ethtool.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/* 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;
|
||||
129
drivers/net/ethernet/sfc/ef100_netdev.c
Normal file
129
drivers/net/ethernet/sfc/ef100_netdev.c
Normal file
@@ -0,0 +1,129 @@
|
||||
// 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);
|
||||
}
|
||||
|
||||
/* 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_start_xmit = ef100_hard_start_xmit,
|
||||
};
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
17
drivers/net/ethernet/sfc/ef100_netdev.h
Normal file
17
drivers/net/ethernet/sfc/ef100_netdev.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* 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);
|
||||
174
drivers/net/ethernet/sfc/ef100_nic.c
Normal file
174
drivers/net/ethernet/sfc/ef100_nic.c
Normal file
@@ -0,0 +1,174 @@
|
||||
// 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
|
||||
|
||||
/* MCDI
|
||||
*/
|
||||
static int ef100_get_warm_boot_count(struct efx_nic *efx)
|
||||
{
|
||||
efx_dword_t reg;
|
||||
|
||||
efx_readd(efx, ®, 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 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;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
.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,
|
||||
|
||||
.ev_probe = ef100_ev_probe,
|
||||
.irq_handle_msi = ef100_msi_interrupt,
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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. */
|
||||
|
||||
efx->max_vis = EF100_MAX_VIS;
|
||||
|
||||
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)
|
||||
{
|
||||
return ef100_probe_main(efx);
|
||||
}
|
||||
|
||||
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;
|
||||
kfree(nic_data);
|
||||
efx->nic_data = NULL;
|
||||
}
|
||||
26
drivers/net/ethernet/sfc/ef100_nic.h
Normal file
26
drivers/net/ethernet/sfc/ef100_nic.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* 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;
|
||||
u16 warm_boot_count;
|
||||
};
|
||||
|
||||
#define efx_ef100_has_cap(caps, flag) \
|
||||
(!!((caps) & BIT_ULL(MC_CMD_GET_CAPABILITIES_V4_OUT_ ## flag ## _LBN)))
|
||||
25
drivers/net/ethernet/sfc/ef100_rx.c
Normal file
25
drivers/net/ethernet/sfc/ef100_rx.c
Normal file
@@ -0,0 +1,25 @@
|
||||
// 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"
|
||||
|
||||
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;
|
||||
}
|
||||
19
drivers/net/ethernet/sfc/ef100_rx.h
Normal file
19
drivers/net/ethernet/sfc/ef100_rx.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/* 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_packet(struct efx_channel *channel);
|
||||
|
||||
#endif
|
||||
32
drivers/net/ethernet/sfc/ef100_tx.c
Normal file
32
drivers/net/ethernet/sfc/ef100_tx.c
Normal file
@@ -0,0 +1,32 @@
|
||||
// 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"
|
||||
|
||||
/* 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;
|
||||
}
|
||||
18
drivers/net/ethernet/sfc/ef100_tx.h
Normal file
18
drivers/net/ethernet/sfc/ef100_tx.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/* 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"
|
||||
|
||||
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 */
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#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);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user