linux/drivers/net/ethernet/freescale/gianfar.c

// SPDX-License-Identifier: GPL-2.0-or-later
/* drivers/net/ethernet/freescale/gianfar.c
 *
 * Gianfar Ethernet Driver
 * This driver is designed for the non-CPM ethernet controllers
 * on the 85xx and 83xx family of integrated processors
 * Based on 8260_io/fcc_enet.c
 *
 * Author: Andy Fleming
 * Maintainer: Kumar Gala
 * Modifier: Sandeep Gopalpet <[email protected]>
 *
 * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc.
 * Copyright 2007 MontaVista Software, Inc.
 *
 *  Gianfar:  AKA Lambda Draconis, "Dragon"
 *  RA 11 31 24.2
 *  Dec +69 19 52
 *  V 3.84
 *  B-V +1.62
 *
 *  Theory of operation
 *
 *  The driver is initialized through of_device. Configuration information
 *  is therefore conveyed through an OF-style device tree.
 *
 *  The Gianfar Ethernet Controller uses a ring of buffer
 *  descriptors.  The beginning is indicated by a register
 *  pointing to the physical address of the start of the ring.
 *  The end is determined by a "wrap" bit being set in the
 *  last descriptor of the ring.
 *
 *  When a packet is received, the RXF bit in the
 *  IEVENT register is set, triggering an interrupt when the
 *  corresponding bit in the IMASK register is also set (if
 *  interrupt coalescing is active, then the interrupt may not
 *  happen immediately, but will wait until either a set number
 *  of frames or amount of time have passed).  In NAPI, the
 *  interrupt handler will signal there is work to be done, and
 *  exit. This method will start at the last known empty
 *  descriptor, and process every subsequent descriptor until there
 *  are none left with data (NAPI will stop after a set number of
 *  packets to give time to other tasks, but will eventually
 *  process all the packets).  The data arrives inside a
 *  pre-allocated skb, and so after the skb is passed up to the
 *  stack, a new skb must be allocated, and the address field in
 *  the buffer descriptor must be updated to indicate this new
 *  skb.
 *
 *  When the kernel requests that a packet be transmitted, the
 *  driver starts where it left off last time, and points the
 *  descriptor at the buffer which was passed in.  The driver
 *  then informs the DMA engine that there are packets ready to
 *  be transmitted.  Once the controller is finished transmitting
 *  the packet, an interrupt may be triggered (under the same
 *  conditions as for reception, but depending on the TXF bit).
 *  The driver then cleans up the buffer.
 */

#define pr_fmt(fmt)

#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_vlan.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_mdio.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/in.h>
#include <linux/net_tstamp.h>

#include <asm/io.h>
#ifdef CONFIG_PPC
#include <asm/reg.h>
#include <asm/mpc85xx.h>
#endif
#include <asm/irq.h>
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/phy_fixed.h>
#include <linux/of.h>
#include <linux/of_net.h>

#include "gianfar.h"

#define TX_TIMEOUT

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

static void gfar_init_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
			    dma_addr_t buf)
{}

static void gfar_init_tx_rx_base(struct gfar_private *priv)
{}

static void gfar_init_rqprm(struct gfar_private *priv)
{}

static void gfar_rx_offload_en(struct gfar_private *priv)
{}

static void gfar_mac_rx_config(struct gfar_private *priv)
{}

static void gfar_mac_tx_config(struct gfar_private *priv)
{}

static void gfar_configure_coalescing(struct gfar_private *priv,
			       unsigned long tx_mask, unsigned long rx_mask)
{}

static void gfar_configure_coalescing_all(struct gfar_private *priv)
{}

static void gfar_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{}

/* Set the appropriate hash bit for the given addr */
/* The algorithm works like so:
 * 1) Take the Destination Address (ie the multicast address), and
 * do a CRC on it (little endian), and reverse the bits of the
 * result.
 * 2) Use the 8 most significant bits as a hash into a 256-entry
 * table.  The table is controlled through 8 32-bit registers:
 * gaddr0-7.  gaddr0's MSB is entry 0, and gaddr7's LSB is
 * gaddr7.  This means that the 3 most significant bits in the
 * hash index which gaddr register to use, and the 5 other bits
 * indicate which bit (assuming an IBM numbering scheme, which
 * for PowerPC (tm) is usually the case) in the register holds
 * the entry.
 */
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr)
{}

/* There are multiple MAC Address register pairs on some controllers
 * This function sets the numth pair to a given address
 */
static void gfar_set_mac_for_addr(struct net_device *dev, int num,
				  const u8 *addr)
{}

static int gfar_set_mac_addr(struct net_device *dev, void *p)
{}

static void gfar_ints_disable(struct gfar_private *priv)
{}

static void gfar_ints_enable(struct gfar_private *priv)
{}

static int gfar_alloc_tx_queues(struct gfar_private *priv)
{}

static int gfar_alloc_rx_queues(struct gfar_private *priv)
{}

static void gfar_free_tx_queues(struct gfar_private *priv)
{}

static void gfar_free_rx_queues(struct gfar_private *priv)
{}

static void unmap_group_regs(struct gfar_private *priv)
{}

static void free_gfar_dev(struct gfar_private *priv)
{}

static void disable_napi(struct gfar_private *priv)
{}

static void enable_napi(struct gfar_private *priv)
{}

static int gfar_parse_group(struct device_node *np,
			    struct gfar_private *priv, const char *model)
{}

static int gfar_of_group_count(struct device_node *np)
{}

/* Reads the controller's registers to determine what interface
 * connects it to the PHY.
 */
static phy_interface_t gfar_get_interface(struct net_device *dev)
{}

static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
{}

static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar,
				   u32 class)
{}

static void gfar_init_filer_table(struct gfar_private *priv)
{}

#ifdef CONFIG_PPC
static void __gfar_detect_errata_83xx(struct gfar_private *priv)
{
	unsigned int pvr = mfspr(SPRN_PVR);
	unsigned int svr = mfspr(SPRN_SVR);
	unsigned int mod = (svr >> 16) & 0xfff6; /* w/o E suffix */
	unsigned int rev = svr & 0xffff;

	/* MPC8313 Rev 2.0 and higher; All MPC837x */
	if ((pvr == 0x80850010 && mod == 0x80b0 && rev >= 0x0020) ||
	    (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
		priv->errata |= GFAR_ERRATA_74;

	/* MPC8313 and MPC837x all rev */
	if ((pvr == 0x80850010 && mod == 0x80b0) ||
	    (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
		priv->errata |= GFAR_ERRATA_76;

	/* MPC8313 Rev < 2.0 */
	if (pvr == 0x80850010 && mod == 0x80b0 && rev < 0x0020)
		priv->errata |= GFAR_ERRATA_12;
}

static void __gfar_detect_errata_85xx(struct gfar_private *priv)
{
	unsigned int svr = mfspr(SPRN_SVR);

	if ((SVR_SOC_VER(svr) == SVR_8548) && (SVR_REV(svr) == 0x20))
		priv->errata |= GFAR_ERRATA_12;
	/* P2020/P1010 Rev 1; MPC8548 Rev 2 */
	if (((SVR_SOC_VER(svr) == SVR_P2020) && (SVR_REV(svr) < 0x20)) ||
	    ((SVR_SOC_VER(svr) == SVR_P2010) && (SVR_REV(svr) < 0x20)) ||
	    ((SVR_SOC_VER(svr) == SVR_8548) && (SVR_REV(svr) < 0x31)))
		priv->errata |= GFAR_ERRATA_76; /* aka eTSEC 20 */
}
#endif

static void gfar_detect_errata(struct gfar_private *priv)
{}

static void gfar_init_addr_hash_table(struct gfar_private *priv)
{}

static int __gfar_is_rx_idle(struct gfar_private *priv)
{}

/* Halt the receive and transmit queues */
static void gfar_halt_nodisable(struct gfar_private *priv)
{}

/* Halt the receive and transmit queues */
static void gfar_halt(struct gfar_private *priv)
{}

static void free_skb_tx_queue(struct gfar_priv_tx_q *tx_queue)
{}

static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue)
{}

/* If there are any tx skbs or rx skbs still around, free them.
 * Then free tx_skbuff and rx_skbuff
 */
static void free_skb_resources(struct gfar_private *priv)
{}

void stop_gfar(struct net_device *dev)
{}

static void gfar_start(struct gfar_private *priv)
{}

static bool gfar_new_page(struct gfar_priv_rx_q *rxq, struct gfar_rx_buff *rxb)
{}

static void gfar_rx_alloc_err(struct gfar_priv_rx_q *rx_queue)
{}

static void gfar_alloc_rx_buffs(struct gfar_priv_rx_q *rx_queue,
				int alloc_cnt)
{}

static void gfar_init_bds(struct net_device *ndev)
{}

static int gfar_alloc_skb_resources(struct net_device *ndev)
{}

/* Bring the controller up and running */
int startup_gfar(struct net_device *ndev)
{}

static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
{}

static noinline void gfar_update_link_state(struct gfar_private *priv)
{}

/* Called every time the controller might need to be made
 * aware of new link state.  The PHY code conveys this
 * information through variables in the phydev structure, and this
 * function converts those variables into the appropriate
 * register values, and can bring down the device if needed.
 */
static void adjust_link(struct net_device *dev)
{}

/* Initialize TBI PHY interface for communicating with the
 * SERDES lynx PHY on the chip.  We communicate with this PHY
 * through the MDIO bus on each controller, treating it as a
 * "normal" PHY at the address found in the TBIPA register.  We assume
 * that the TBIPA register is valid.  Either the MDIO bus code will set
 * it to a value that doesn't conflict with other PHYs on the bus, or the
 * value doesn't matter, as there are no other PHYs on the bus.
 */
static void gfar_configure_serdes(struct net_device *dev)
{}

/* Initializes driver's PHY state, and attaches to the PHY.
 * Returns 0 on success.
 */
static int init_phy(struct net_device *dev)
{}

static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb)
{}

static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb,
				    int fcb_length)
{}

static inline void gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
{}

static inline struct txbd8 *skip_txbd(struct txbd8 *bdp, int stride,
				      struct txbd8 *base, int ring_size)
{}

static inline struct txbd8 *next_txbd(struct txbd8 *bdp, struct txbd8 *base,
				      int ring_size)
{}

/* eTSEC12: csum generation not supported for some fcb offsets */
static inline bool gfar_csum_errata_12(struct gfar_private *priv,
				       unsigned long fcb_addr)
{}

/* eTSEC76: csum generation for frames larger than 2500 may
 * cause excess delays before start of transmission
 */
static inline bool gfar_csum_errata_76(struct gfar_private *priv,
				       unsigned int len)
{}

/* This is called by the kernel when a frame is ready for transmission.
 * It is pointed to by the dev->hard_start_xmit function pointer
 */
static netdev_tx_t gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
{}

/* Changes the mac address if the controller is not running. */
static int gfar_set_mac_address(struct net_device *dev)
{}

static int gfar_change_mtu(struct net_device *dev, int new_mtu)
{}

static void reset_gfar(struct net_device *ndev)
{}

/* gfar_reset_task gets scheduled when a packet has not been
 * transmitted after a set amount of time.
 * For now, assume that clearing out all the structures, and
 * starting over will fix the problem.
 */
static void gfar_reset_task(struct work_struct *work)
{}

static void gfar_timeout(struct net_device *dev, unsigned int txqueue)
{}

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

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

static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{}

/* Interrupt Handler for Transmit complete */
static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
{}

static void count_errors(u32 lstatus, struct net_device *ndev)
{}

static irqreturn_t gfar_receive(int irq, void *grp_id)
{}

/* Interrupt Handler for Transmit complete */
static irqreturn_t gfar_transmit(int irq, void *grp_id)
{}

static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus,
			     struct sk_buff *skb, bool first)
{}

static void gfar_reuse_rx_page(struct gfar_priv_rx_q *rxq,
			       struct gfar_rx_buff *old_rxb)
{}

static struct sk_buff *gfar_get_next_rxbuff(struct gfar_priv_rx_q *rx_queue,
					    u32 lstatus, struct sk_buff *skb)
{}

static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
{}

/* gfar_process_frame() -- handle one incoming packet if skb isn't NULL. */
static void gfar_process_frame(struct net_device *ndev, struct sk_buff *skb)
{}

/* gfar_clean_rx_ring() -- Processes each frame in the rx ring
 * until the budget/quota has been reached. Returns the number
 * of frames handled
 */
static int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue,
			      int rx_work_limit)
{}

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

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

/* GFAR error interrupt handler */
static irqreturn_t gfar_error(int irq, void *grp_id)
{}

/* The interrupt handler for devices with one interrupt */
static irqreturn_t gfar_interrupt(int irq, void *grp_id)
{}

#ifdef CONFIG_NET_POLL_CONTROLLER
/* Polling 'interrupt' - used by things like netconsole to send skbs
 * without having to re-enable interrupts. It's not called while
 * the interrupt routine is executing.
 */
static void gfar_netpoll(struct net_device *dev)
{}
#endif

static void free_grp_irqs(struct gfar_priv_grp *grp)
{}

static int register_grp_irqs(struct gfar_priv_grp *grp)
{}

static void gfar_free_irq(struct gfar_private *priv)
{}

static int gfar_request_irq(struct gfar_private *priv)
{}

/* Called when something needs to use the ethernet device
 * Returns 0 for success.
 */
static int gfar_enet_open(struct net_device *dev)
{}

/* Stops the kernel queue, and halts the controller */
static int gfar_close(struct net_device *dev)
{}

/* Clears each of the exact match registers to zero, so they
 * don't interfere with normal reception
 */
static void gfar_clear_exact_match(struct net_device *dev)
{}

/* Update the hash table based on the current list of multicast
 * addresses we subscribe to.  Also, change the promiscuity of
 * the device based on the flags (this function is called
 * whenever dev->flags is changed
 */
static void gfar_set_multi(struct net_device *dev)
{}

void gfar_mac_reset(struct gfar_private *priv)
{}

static void gfar_hw_init(struct gfar_private *priv)
{}

static const struct net_device_ops gfar_netdev_ops =;

/* Set up the ethernet device structure, private data,
 * and anything else we need before we start
 */
static int gfar_probe(struct platform_device *ofdev)
{}

static void gfar_remove(struct platform_device *ofdev)
{}

#ifdef CONFIG_PM

static void __gfar_filer_disable(struct gfar_private *priv)
{}

static void __gfar_filer_enable(struct gfar_private *priv)
{}

/* Filer rules implementing wol capabilities */
static void gfar_filer_config_wol(struct gfar_private *priv)
{}

static void gfar_filer_restore_table(struct gfar_private *priv)
{}

/* gfar_start() for Rx only and with the FGPI filer interrupt enabled */
static void gfar_start_wol_filer(struct gfar_private *priv)
{}

static int gfar_suspend(struct device *dev)
{}

static int gfar_resume(struct device *dev)
{}

static int gfar_restore(struct device *dev)
{}

static const struct dev_pm_ops gfar_pm_ops =;

#define GFAR_PM_OPS

#else

#define GFAR_PM_OPS

#endif

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

/* Structure for a device driver */
static struct platform_driver gfar_driver =;

module_platform_driver();