linux/drivers/net/ethernet/engleder/tsnep_main.c

// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2021 Gerhard Engleder <[email protected]> */

/* TSN endpoint Ethernet MAC driver
 *
 * The TSN endpoint Ethernet MAC is a FPGA based network device for real-time
 * communication. It is designed for endpoints within TSN (Time Sensitive
 * Networking) networks; e.g., for PLCs in the industrial automation case.
 *
 * It supports multiple TX/RX queue pairs. The first TX/RX queue pair is used
 * by the driver.
 *
 * More information can be found here:
 * - www.embedded-experts.at/tsn
 * - www.engleder-embedded.com
 */

#include "tsnep.h"
#include "tsnep_hw.h"

#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/of_mdio.h>
#include <linux/interrupt.h>
#include <linux/etherdevice.h>
#include <linux/phy.h>
#include <linux/iopoll.h>
#include <linux/bpf.h>
#include <linux/bpf_trace.h>
#include <net/page_pool/helpers.h>
#include <net/xdp_sock_drv.h>

#define TSNEP_RX_OFFSET
#define TSNEP_HEADROOM
#define TSNEP_MAX_RX_BUF_SIZE
/* XSK buffer shall store at least Q-in-Q frame */
#define TSNEP_XSK_RX_BUF_SIZE

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
#define DMA_ADDR_HIGH(dma_addr)
#else
#define DMA_ADDR_HIGH
#endif
#define DMA_ADDR_LOW(dma_addr)

#define TSNEP_COALESCE_USECS_DEFAULT
#define TSNEP_COALESCE_USECS_MAX

/* mapping type */
#define TSNEP_TX_TYPE_MAP
#define TSNEP_TX_TYPE_MAP_PAGE
#define TSNEP_TX_TYPE_INLINE
/* buffer type */
#define TSNEP_TX_TYPE_SKB
#define TSNEP_TX_TYPE_SKB_MAP
#define TSNEP_TX_TYPE_SKB_INLINE
#define TSNEP_TX_TYPE_SKB_FRAG
#define TSNEP_TX_TYPE_SKB_FRAG_MAP_PAGE
#define TSNEP_TX_TYPE_SKB_FRAG_INLINE
#define TSNEP_TX_TYPE_XDP_TX
#define TSNEP_TX_TYPE_XDP_NDO
#define TSNEP_TX_TYPE_XDP_NDO_MAP_PAGE
#define TSNEP_TX_TYPE_XDP
#define TSNEP_TX_TYPE_XSK

#define TSNEP_XDP_TX
#define TSNEP_XDP_REDIRECT

static void tsnep_enable_irq(struct tsnep_adapter *adapter, u32 mask)
{}

static void tsnep_disable_irq(struct tsnep_adapter *adapter, u32 mask)
{}

static irqreturn_t tsnep_irq(int irq, void *arg)
{}

static irqreturn_t tsnep_irq_txrx(int irq, void *arg)
{}

int tsnep_set_irq_coalesce(struct tsnep_queue *queue, u32 usecs)
{}

u32 tsnep_get_irq_coalesce(struct tsnep_queue *queue)
{}

static int tsnep_mdiobus_read(struct mii_bus *bus, int addr, int regnum)
{}

static int tsnep_mdiobus_write(struct mii_bus *bus, int addr, int regnum,
			       u16 val)
{}

static void tsnep_set_link_mode(struct tsnep_adapter *adapter)
{}

static void tsnep_phy_link_status_change(struct net_device *netdev)
{}

static int tsnep_phy_loopback(struct tsnep_adapter *adapter, bool enable)
{}

static int tsnep_phy_open(struct tsnep_adapter *adapter)
{}

static void tsnep_phy_close(struct tsnep_adapter *adapter)
{}

static void tsnep_tx_ring_cleanup(struct tsnep_tx *tx)
{}

static int tsnep_tx_ring_create(struct tsnep_tx *tx)
{}

static void tsnep_tx_init(struct tsnep_tx *tx)
{}

static void tsnep_tx_enable(struct tsnep_tx *tx)
{}

static void tsnep_tx_disable(struct tsnep_tx *tx, struct napi_struct *napi)
{}

static void tsnep_tx_activate(struct tsnep_tx *tx, int index, int length,
			      bool last)
{}

static int tsnep_tx_desc_available(struct tsnep_tx *tx)
{}

static int tsnep_tx_map_frag(skb_frag_t *frag, struct tsnep_tx_entry *entry,
			     struct device *dmadev, dma_addr_t *dma)
{}

static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count)
{}

static int tsnep_tx_unmap(struct tsnep_tx *tx, int index, int count)
{}

static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
					 struct tsnep_tx *tx)
{}

static int tsnep_xdp_tx_map(struct xdp_frame *xdpf, struct tsnep_tx *tx,
			    struct skb_shared_info *shinfo, int count, u32 type)
{}

/* This function requires __netif_tx_lock is held by the caller. */
static bool tsnep_xdp_xmit_frame_ring(struct xdp_frame *xdpf,
				      struct tsnep_tx *tx, u32 type)
{}

static void tsnep_xdp_xmit_flush(struct tsnep_tx *tx)
{}

static bool tsnep_xdp_xmit_back(struct tsnep_adapter *adapter,
				struct xdp_buff *xdp,
				struct netdev_queue *tx_nq, struct tsnep_tx *tx,
				bool zc)
{}

static int tsnep_xdp_tx_map_zc(struct xdp_desc *xdpd, struct tsnep_tx *tx)
{}

static void tsnep_xdp_xmit_frame_ring_zc(struct xdp_desc *xdpd,
					 struct tsnep_tx *tx)
{}

static void tsnep_xdp_xmit_zc(struct tsnep_tx *tx)
{}

static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)
{}

static bool tsnep_tx_pending(struct tsnep_tx *tx)
{}

static int tsnep_tx_open(struct tsnep_tx *tx)
{}

static void tsnep_tx_close(struct tsnep_tx *tx)
{}

static void tsnep_rx_ring_cleanup(struct tsnep_rx *rx)
{}

static int tsnep_rx_ring_create(struct tsnep_rx *rx)
{}

static void tsnep_rx_init(struct tsnep_rx *rx)
{}

static void tsnep_rx_enable(struct tsnep_rx *rx)
{}

static void tsnep_rx_disable(struct tsnep_rx *rx)
{}

static int tsnep_rx_desc_available(struct tsnep_rx *rx)
{}

static void tsnep_rx_free_page_buffer(struct tsnep_rx *rx)
{}

static int tsnep_rx_alloc_page_buffer(struct tsnep_rx *rx)
{}

static void tsnep_rx_set_page(struct tsnep_rx *rx, struct tsnep_rx_entry *entry,
			      struct page *page)
{}

static int tsnep_rx_alloc_buffer(struct tsnep_rx *rx, int index)
{}

static void tsnep_rx_reuse_buffer(struct tsnep_rx *rx, int index)
{}

static void tsnep_rx_activate(struct tsnep_rx *rx, int index)
{}

static int tsnep_rx_alloc(struct tsnep_rx *rx, int count, bool reuse)
{}

static int tsnep_rx_refill(struct tsnep_rx *rx, int count, bool reuse)
{}

static void tsnep_rx_set_xdp(struct tsnep_rx *rx, struct tsnep_rx_entry *entry,
			     struct xdp_buff *xdp)
{}

static void tsnep_rx_reuse_buffer_zc(struct tsnep_rx *rx, int index)
{}

static int tsnep_rx_alloc_zc(struct tsnep_rx *rx, int count, bool reuse)
{}

static void tsnep_rx_free_zc(struct tsnep_rx *rx)
{}

static int tsnep_rx_refill_zc(struct tsnep_rx *rx, int count, bool reuse)
{}

static void tsnep_xsk_rx_need_wakeup(struct tsnep_rx *rx, int desc_available)
{}

static bool tsnep_xdp_run_prog(struct tsnep_rx *rx, struct bpf_prog *prog,
			       struct xdp_buff *xdp, int *status,
			       struct netdev_queue *tx_nq, struct tsnep_tx *tx)
{}

static bool tsnep_xdp_run_prog_zc(struct tsnep_rx *rx, struct bpf_prog *prog,
				  struct xdp_buff *xdp, int *status,
				  struct netdev_queue *tx_nq,
				  struct tsnep_tx *tx)
{}

static void tsnep_finalize_xdp(struct tsnep_adapter *adapter, int status,
			       struct netdev_queue *tx_nq, struct tsnep_tx *tx)
{}

static struct sk_buff *tsnep_build_skb(struct tsnep_rx *rx, struct page *page,
				       int length)
{}

static void tsnep_rx_page(struct tsnep_rx *rx, struct napi_struct *napi,
			  struct page *page, int length)
{}

static int tsnep_rx_poll(struct tsnep_rx *rx, struct napi_struct *napi,
			 int budget)
{}

static int tsnep_rx_poll_zc(struct tsnep_rx *rx, struct napi_struct *napi,
			    int budget)
{}

static bool tsnep_rx_pending(struct tsnep_rx *rx)
{}

static int tsnep_rx_open(struct tsnep_rx *rx)
{}

static void tsnep_rx_close(struct tsnep_rx *rx)
{}

static void tsnep_rx_reopen(struct tsnep_rx *rx)
{}

static void tsnep_rx_reopen_xsk(struct tsnep_rx *rx)
{}

static bool tsnep_pending(struct tsnep_queue *queue)
{}

static int tsnep_poll(struct napi_struct *napi, int budget)
{}

static int tsnep_request_irq(struct tsnep_queue *queue, bool first)
{}

static void tsnep_free_irq(struct tsnep_queue *queue, bool first)
{}

static void tsnep_queue_close(struct tsnep_queue *queue, bool first)
{}

static int tsnep_queue_open(struct tsnep_adapter *adapter,
			    struct tsnep_queue *queue, bool first)
{}

static void tsnep_queue_enable(struct tsnep_queue *queue)
{}

static void tsnep_queue_disable(struct tsnep_queue *queue)
{}

static int tsnep_netdev_open(struct net_device *netdev)
{}

static int tsnep_netdev_close(struct net_device *netdev)
{}

int tsnep_enable_xsk(struct tsnep_queue *queue, struct xsk_buff_pool *pool)
{}

void tsnep_disable_xsk(struct tsnep_queue *queue)
{}

static netdev_tx_t tsnep_netdev_xmit_frame(struct sk_buff *skb,
					   struct net_device *netdev)
{}

static int tsnep_netdev_ioctl(struct net_device *netdev, struct ifreq *ifr,
			      int cmd)
{}

static void tsnep_netdev_set_multicast(struct net_device *netdev)
{}

static void tsnep_netdev_get_stats64(struct net_device *netdev,
				     struct rtnl_link_stats64 *stats)
{}

static void tsnep_mac_set_address(struct tsnep_adapter *adapter, u8 *addr)
{}

static int tsnep_netdev_set_mac_address(struct net_device *netdev, void *addr)
{}

static int tsnep_netdev_set_features(struct net_device *netdev,
				     netdev_features_t features)
{}

static ktime_t tsnep_netdev_get_tstamp(struct net_device *netdev,
				       const struct skb_shared_hwtstamps *hwtstamps,
				       bool cycles)
{}

static int tsnep_netdev_bpf(struct net_device *dev, struct netdev_bpf *bpf)
{}

static struct tsnep_tx *tsnep_xdp_get_tx(struct tsnep_adapter *adapter, u32 cpu)
{}

static int tsnep_netdev_xdp_xmit(struct net_device *dev, int n,
				 struct xdp_frame **xdp, u32 flags)
{}

static int tsnep_netdev_xsk_wakeup(struct net_device *dev, u32 queue_id,
				   u32 flags)
{}

static const struct net_device_ops tsnep_netdev_ops =;

static int tsnep_mac_init(struct tsnep_adapter *adapter)
{}

static int tsnep_mdio_init(struct tsnep_adapter *adapter)
{}

static int tsnep_phy_init(struct tsnep_adapter *adapter)
{}

static int tsnep_queue_init(struct tsnep_adapter *adapter, int queue_count)
{}

static int tsnep_probe(struct platform_device *pdev)
{}

static void tsnep_remove(struct platform_device *pdev)
{}

static const struct of_device_id tsnep_of_match[] =;
MODULE_DEVICE_TABLE(of, tsnep_of_match);

static struct platform_driver tsnep_driver =;
module_platform_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();