Commit cfb5d7b7 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ravb-gigabit'

Biju Das says:

====================
Fillup stubs for Gigabit Ethernet driver support

The DMAC and EMAC blocks of Gigabit Ethernet IP found on RZ/G2L SoC are
similar to the R-Car Ethernet AVB IP.

The Gigabit Ethernet IP consists of Ethernet controller (E-MAC), Internal
TCP/IP Offload Engine (TOE)  and Dedicated Direct memory access controller
(DMAC).

With a few changes in the driver we can support both IPs.

This patch series is for adding Gigabit ethernet driver support to RZ/G2L SoC.

The number of patches after incorporatng RFC review comments is 18.
So split the patches into 2 patchsets (10 + 8).

This series is the second patchset, aims to fillup all the stubs for the
Gigabit Ethernet driver.

This patch series depend upon [1]
[1] https://lore.kernel.org/linux-renesas-soc/20211001150636.7500-1-biju.das.jz@bp.renesas.com/T/#t



RFC->V1:
 * used rx_max_buf_size instead of rx_2k_buffers feature bit.
 * renamed "rgeth" to "gbeth".
 * renamed ravb_rx_ring_free to ravb_rx_ring_free_rcar
 * renamed ravb_rx_ring_format to ravb_rx_ring_format_rcar
 * renamed ravb_alloc_rx_desc to ravb_alloc_rx_desc_rcar
 * renamed ravb_rcar_rx to ravb_rx_rcar
 * Added Sergey's Rb tag for patch #6.
 * Moved CSR0 initialization to patch #8.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6b7b0c30 16a23519
Loading
Loading
Loading
Loading
+30 −9
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ enum ravb_reg {
	RQC3	= 0x00A0,
	RQC4	= 0x00A4,
	RPC	= 0x00B0,
	RTC	= 0x00B4,	/* R-Car Gen3 and RZ/G2L only */
	UFCW	= 0x00BC,
	UFCS	= 0x00C0,
	UFCV0	= 0x00C4,
@@ -187,13 +188,14 @@ enum ravb_reg {
	PIR	= 0x0520,
	PSR	= 0x0528,
	PIPR	= 0x052c,
	CXR31	= 0x0530,	/* RZ/G2L only */
	MPR	= 0x0558,
	PFTCR	= 0x055c,
	PFRCR	= 0x0560,
	GECMR	= 0x05b0,
	MAHR	= 0x05c0,
	MALR	= 0x05c8,
	TROCR	= 0x0700,	/* R-Car Gen3 only */
	TROCR	= 0x0700,	/* R-Car Gen3 and RZ/G2L only */
	CEFCR	= 0x0740,
	FRECR	= 0x0748,
	TSFRCR	= 0x0750,
@@ -810,10 +812,11 @@ enum ECMR_BIT {
	ECMR_TXF	= 0x00010000,	/* Documented for R-Car Gen3 only */
	ECMR_RXF	= 0x00020000,
	ECMR_PFR	= 0x00040000,
	ECMR_ZPF	= 0x00080000,	/* Documented for R-Car Gen3 only */
	ECMR_ZPF	= 0x00080000,	/* Documented for R-Car Gen3 and RZ/G2L */
	ECMR_RZPF	= 0x00100000,
	ECMR_DPAD	= 0x00200000,
	ECMR_RCSC	= 0x00800000,
	ECMR_RCPT	= 0x02000000,	/* Documented for RZ/G2L only */
	ECMR_TRCCM	= 0x04000000,
};

@@ -823,6 +826,7 @@ enum ECSR_BIT {
	ECSR_MPD	= 0x00000002,
	ECSR_LCHNG	= 0x00000004,
	ECSR_PHYI	= 0x00000008,
	ECSR_PFRI	= 0x00000010,
};

/* ECSIPR */
@@ -860,6 +864,10 @@ enum GECMR_BIT {
	GECMR_SPEED		= 0x00000001,
	GECMR_SPEED_100		= 0x00000000,
	GECMR_SPEED_1000	= 0x00000001,
	GBETH_GECMR_SPEED	= 0x00000030,
	GBETH_GECMR_SPEED_10	= 0x00000000,
	GBETH_GECMR_SPEED_100	= 0x00000010,
	GBETH_GECMR_SPEED_1000	= 0x00000020,
};

/* The Ethernet AVB descriptor definitions. */
@@ -949,6 +957,11 @@ enum RAVB_QUEUE {
	RAVB_NC,	/* Network Control Queue */
};

enum CXR31_BIT {
	CXR31_SEL_LINK0	= 0x00000001,
	CXR31_SEL_LINK1	= 0x00000008,
};

#define DBAT_ENTRY_NUM	22
#define RX_QUEUE_OFFSET	4
#define NUM_RX_QUEUE	2
@@ -956,6 +969,8 @@ enum RAVB_QUEUE {

#define RX_BUF_SZ	(2048 - ETH_FCS_LEN + sizeof(__sum16))

#define GBETH_RX_BUFF_MAX 8192

struct ravb_tstamp_skb {
	struct list_head list;
	struct sk_buff *skb;
@@ -985,8 +1000,8 @@ struct ravb_hw_info {
	void *(*alloc_rx_desc)(struct net_device *ndev, int q);
	bool (*receive)(struct net_device *ndev, int *quota, int q);
	void (*set_rate)(struct net_device *ndev);
	int (*set_rx_csum_feature)(struct net_device *ndev, netdev_features_t features);
	void (*dmac_init)(struct net_device *ndev);
	int (*set_feature)(struct net_device *ndev, netdev_features_t features);
	int (*dmac_init)(struct net_device *ndev);
	void (*emac_init)(struct net_device *ndev);
	const char (*gstrings_stats)[ETH_GSTRING_LEN];
	size_t gstrings_size;
@@ -994,14 +1009,18 @@ struct ravb_hw_info {
	netdev_features_t net_features;
	int stats_len;
	size_t max_rx_len;
	u32 tsrq;
	unsigned aligned_tx: 1;

	/* hardware features */
	unsigned internal_delay:1;	/* AVB-DMAC has internal delays */
	unsigned tx_counters:1;		/* E-MAC has TX counters */
	unsigned multi_irqs:1;		/* AVB-DMAC and E-MAC has multiple irqs */
	unsigned no_ptp_cfg_active:1;	/* AVB-DMAC does not support gPTP active in config mode */
	unsigned ptp_cfg_active:1;	/* AVB-DMAC has gPTP support active in config mode */
	unsigned gptp:1;		/* AVB-DMAC has gPTP support */
	unsigned ccc_gac:1;		/* AVB-DMAC has gPTP support active in config mode */
	unsigned nc_queue:1;		/* AVB-DMAC has NC queue */
	unsigned magic_pkt:1;		/* E-MAC supports magic packet detection */
	unsigned half_duplex:1;		/* E-MAC supports half duplex mode */
};

struct ravb_private {
@@ -1056,6 +1075,8 @@ struct ravb_private {
	unsigned rgmii_override:1;	/* Deprecated rgmii-*id behavior */
	unsigned int num_tx_desc;	/* TX descriptors per packet */

	int duplex;

	const struct ravb_hw_info *info;
	struct reset_control *rstc;
};
+332 −120
Original line number Diff line number Diff line
@@ -83,7 +83,24 @@ static int ravb_config(struct net_device *ndev)
	return error;
}

static void ravb_set_rate(struct net_device *ndev)
static void ravb_set_rate_gbeth(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);

	switch (priv->speed) {
	case 10:                /* 10BASE */
		ravb_write(ndev, GBETH_GECMR_SPEED_10, GECMR);
		break;
	case 100:               /* 100BASE */
		ravb_write(ndev, GBETH_GECMR_SPEED_100, GECMR);
		break;
	case 1000:              /* 1000BASE */
		ravb_write(ndev, GBETH_GECMR_SPEED_1000, GECMR);
		break;
	}
}

static void ravb_set_rate_rcar(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);

@@ -217,6 +234,11 @@ static int ravb_tx_free(struct net_device *ndev, int q, bool free_txed_only)
	return free_num;
}

static void ravb_rx_ring_free_gbeth(struct net_device *ndev, int q)
{
	/* Place holder */
}

static void ravb_rx_ring_free(struct net_device *ndev, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
@@ -283,6 +305,11 @@ static void ravb_ring_free(struct net_device *ndev, int q)
	priv->tx_skb[q] = NULL;
}

static void ravb_rx_ring_format_gbeth(struct net_device *ndev, int q)
{
	/* Place holder */
}

static void ravb_rx_ring_format(struct net_device *ndev, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
@@ -356,6 +383,12 @@ static void ravb_ring_format(struct net_device *ndev, int q)
	desc->dptr = cpu_to_le32((u32)priv->tx_desc_dma[q]);
}

static void *ravb_alloc_rx_desc_gbeth(struct net_device *ndev, int q)
{
	/* Place holder */
	return NULL;
}

static void *ravb_alloc_rx_desc(struct net_device *ndev, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
@@ -426,7 +459,37 @@ static int ravb_ring_init(struct net_device *ndev, int q)
	return -ENOMEM;
}

static void ravb_rcar_emac_init(struct net_device *ndev)
static void ravb_emac_init_gbeth(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);

	/* Receive frame limit set register */
	ravb_write(ndev, GBETH_RX_BUFF_MAX + ETH_FCS_LEN, RFLR);

	/* PAUSE prohibition */
	ravb_write(ndev, ECMR_ZPF | ((priv->duplex > 0) ? ECMR_DM : 0) |
			 ECMR_TE | ECMR_RE | ECMR_RCPT |
			 ECMR_TXF | ECMR_RXF | ECMR_PRM, ECMR);

	ravb_set_rate_gbeth(ndev);

	/* Set MAC address */
	ravb_write(ndev,
		   (ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
		   (ndev->dev_addr[2] << 8)  | (ndev->dev_addr[3]), MAHR);
	ravb_write(ndev, (ndev->dev_addr[4] << 8)  | (ndev->dev_addr[5]), MALR);

	/* E-MAC status register clear */
	ravb_write(ndev, ECSR_ICD | ECSR_LCHNG | ECSR_PFRI, ECSR);

	/* E-MAC interrupt enable register */
	ravb_write(ndev, ECSIPR_ICDIP, ECSIPR);

	ravb_modify(ndev, CXR31, CXR31_SEL_LINK1, 0);
	ravb_modify(ndev, CXR31, CXR31_SEL_LINK0, CXR31_SEL_LINK0);
}

static void ravb_emac_init_rcar(struct net_device *ndev)
{
	/* Receive frame limit set register */
	ravb_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN, RFLR);
@@ -436,7 +499,7 @@ static void ravb_rcar_emac_init(struct net_device *ndev)
		   (ndev->features & NETIF_F_RXCSUM ? ECMR_RCSC : 0) |
		   ECMR_TE | ECMR_RE, ECMR);

	ravb_set_rate(ndev);
	ravb_set_rate_rcar(ndev);

	/* Set MAC address */
	ravb_write(ndev,
@@ -461,10 +524,58 @@ static void ravb_emac_init(struct net_device *ndev)
	info->emac_init(ndev);
}

static void ravb_rcar_dmac_init(struct net_device *ndev)
static int ravb_dmac_init_gbeth(struct net_device *ndev)
{
	int error;

	error = ravb_ring_init(ndev, RAVB_BE);
	if (error)
		return error;

	/* Descriptor format */
	ravb_ring_format(ndev, RAVB_BE);

	/* Set AVB RX */
	ravb_write(ndev, 0x60000000, RCR);

	/* Set Max Frame Length (RTC) */
	ravb_write(ndev, 0x7ffc0000 | GBETH_RX_BUFF_MAX, RTC);

	/* Set FIFO size */
	ravb_write(ndev, 0x00222200, TGC);

	ravb_write(ndev, 0, TCCR);

	/* Frame receive */
	ravb_write(ndev, RIC0_FRE0, RIC0);
	/* Disable FIFO full warning */
	ravb_write(ndev, 0x0, RIC1);
	/* Receive FIFO full error, descriptor empty */
	ravb_write(ndev, RIC2_QFE0 | RIC2_RFFE, RIC2);

	ravb_write(ndev, TIC_FTE0, TIC);

	return 0;
}

static int ravb_dmac_init_rcar(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	int error;

	error = ravb_ring_init(ndev, RAVB_BE);
	if (error)
		return error;
	error = ravb_ring_init(ndev, RAVB_NC);
	if (error) {
		ravb_ring_free(ndev, RAVB_BE);
		return error;
	}

	/* Descriptor format */
	ravb_ring_format(ndev, RAVB_BE);
	ravb_ring_format(ndev, RAVB_NC);

	/* Set AVB RX */
	ravb_write(ndev,
@@ -491,6 +602,8 @@ static void ravb_rcar_dmac_init(struct net_device *ndev)
	ravb_write(ndev, RIC2_QFE0 | RIC2_QFE1 | RIC2_RFFE, RIC2);
	/* Frame transmitted, timestamp FIFO updated */
	ravb_write(ndev, TIC_FTE0 | TIC_FTE1 | TIC_TFUE, TIC);

	return 0;
}

/* Device init function for Ethernet AVB */
@@ -505,20 +618,9 @@ static int ravb_dmac_init(struct net_device *ndev)
	if (error)
		return error;

	error = ravb_ring_init(ndev, RAVB_BE);
	error = info->dmac_init(ndev);
	if (error)
		return error;
	error = ravb_ring_init(ndev, RAVB_NC);
	if (error) {
		ravb_ring_free(ndev, RAVB_BE);
		return error;
	}

	/* Descriptor format */
	ravb_ring_format(ndev, RAVB_BE);
	ravb_ring_format(ndev, RAVB_NC);

	info->dmac_init(ndev);

	/* Setting the control will start the AVB-DMAC process. */
	ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_OPERATION);
@@ -579,6 +681,14 @@ static void ravb_rx_csum(struct sk_buff *skb)
	skb_trim(skb, skb->len - sizeof(__sum16));
}

/* Packet receive function for Gigabit Ethernet */
static bool ravb_rx_gbeth(struct net_device *ndev, int *quota, int q)
{
	/* Place holder */
	return true;
}

/* Packet receive function for Ethernet AVB */
static bool ravb_rcar_rx(struct net_device *ndev, int *quota, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
@@ -717,11 +827,13 @@ static void ravb_rcv_snd_enable(struct net_device *ndev)
/* function for waiting dma process finished */
static int ravb_stop_dma(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	int error;

	/* Wait for stopping the hardware TX process */
	error = ravb_wait(ndev, TCCR,
			  TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3, 0);
	error = ravb_wait(ndev, TCCR, info->tsrq, 0);

	if (error)
		return error;

@@ -859,6 +971,7 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
{
	struct net_device *ndev = dev_id;
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	irqreturn_t result = IRQ_NONE;
	u32 iss;

@@ -875,10 +988,15 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
			result = IRQ_HANDLED;

		/* Network control and best effort queue RX/TX */
		if (info->nc_queue) {
			for (q = RAVB_NC; q >= RAVB_BE; q--) {
				if (ravb_queue_interrupt(ndev, q))
					result = IRQ_HANDLED;
			}
		} else {
			if (ravb_queue_interrupt(ndev, RAVB_BE))
				result = IRQ_HANDLED;
		}
	}

	/* E-MAC status summary */
@@ -1000,6 +1118,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)

	/* Receive error message handling */
	priv->rx_over_errors =  priv->stats[RAVB_BE].rx_over_errors;
	if (info->nc_queue)
		priv->rx_over_errors += priv->stats[RAVB_NC].rx_over_errors;
	if (priv->rx_over_errors != ndev->stats.rx_over_errors)
		ndev->stats.rx_over_errors = priv->rx_over_errors;
@@ -1009,6 +1128,13 @@ static int ravb_poll(struct napi_struct *napi, int budget)
	return budget - quota;
}

static void ravb_set_duplex_gbeth(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);

	ravb_modify(ndev, ECMR, ECMR_DM, priv->duplex > 0 ? ECMR_DM : 0);
}

/* PHY state control function */
static void ravb_adjust_link(struct net_device *ndev)
{
@@ -1025,6 +1151,12 @@ static void ravb_adjust_link(struct net_device *ndev)
		ravb_rcv_snd_disable(ndev);

	if (phydev->link) {
		if (info->half_duplex && phydev->duplex != priv->duplex) {
			new_state = true;
			priv->duplex = phydev->duplex;
			ravb_set_duplex_gbeth(ndev);
		}

		if (phydev->speed != priv->speed) {
			new_state = true;
			priv->speed = phydev->speed;
@@ -1039,6 +1171,8 @@ static void ravb_adjust_link(struct net_device *ndev)
		new_state = true;
		priv->link = 0;
		priv->speed = 0;
		if (info->half_duplex)
			priv->duplex = -1;
	}

	/* Enable TX and RX right over here, if E-MAC change is ignored */
@@ -1061,6 +1195,7 @@ static int ravb_phy_init(struct net_device *ndev)
{
	struct device_node *np = ndev->dev.parent->of_node;
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	struct phy_device *phydev;
	struct device_node *pn;
	phy_interface_t iface;
@@ -1068,6 +1203,7 @@ static int ravb_phy_init(struct net_device *ndev)

	priv->link = 0;
	priv->speed = 0;
	priv->duplex = -1;

	/* Try connecting to PHY */
	pn = of_parse_phandle(np, "phy-handle", 0);
@@ -1106,6 +1242,7 @@ static int ravb_phy_init(struct net_device *ndev)
		netdev_info(ndev, "limited PHY to 100Mbit/s\n");
	}

	if (!info->half_duplex) {
		/* 10BASE, Pause and Asym Pause is not supported */
		phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
		phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
@@ -1115,6 +1252,7 @@ static int ravb_phy_init(struct net_device *ndev)
		/* Half Duplex is not supported */
		phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
		phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
	}

	phy_attached_info(phydev);

@@ -1208,11 +1346,14 @@ static void ravb_get_ethtool_stats(struct net_device *ndev,
				   struct ethtool_stats *estats, u64 *data)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	int num_rx_q;
	int i = 0;
	int q;

	num_rx_q = info->nc_queue ? NUM_RX_QUEUE : 1;
	/* Device-specific stats */
	for (q = RAVB_BE; q < NUM_RX_QUEUE; q++) {
	for (q = RAVB_BE; q < num_rx_q; q++) {
		struct net_device_stats *stats = &priv->stats[q];

		data[i++] = priv->cur_rx[q];
@@ -1274,7 +1415,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
	if (netif_running(ndev)) {
		netif_device_detach(ndev);
		/* Stop PTP Clock driver */
		if (info->no_ptp_cfg_active)
		if (info->gptp)
			ravb_ptp_stop(ndev);
		/* Wait for DMA stopping */
		error = ravb_stop_dma(ndev);
@@ -1287,6 +1428,7 @@ static int ravb_set_ringparam(struct net_device *ndev,

		/* Free all the skb's in the RX queue and the DMA buffers. */
		ravb_ring_free(ndev, RAVB_BE);
		if (info->nc_queue)
			ravb_ring_free(ndev, RAVB_NC);
	}

@@ -1306,7 +1448,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
		ravb_emac_init(ndev);

		/* Initialise PTP Clock driver */
		if (info->no_ptp_cfg_active)
		if (info->gptp)
			ravb_ptp_init(ndev, priv->pdev);

		netif_device_attach(ndev);
@@ -1319,6 +1461,7 @@ static int ravb_get_ts_info(struct net_device *ndev,
			    struct ethtool_ts_info *info)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *hw_info = priv->info;

	info->so_timestamping =
		SOF_TIMESTAMPING_TX_SOFTWARE |
@@ -1332,6 +1475,7 @@ static int ravb_get_ts_info(struct net_device *ndev,
		(1 << HWTSTAMP_FILTER_NONE) |
		(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
		(1 << HWTSTAMP_FILTER_ALL);
	if (hw_info->gptp || hw_info->ccc_gac)
		info->phc_index = ptp_clock_index(priv->ptp.clock);

	return 0;
@@ -1348,8 +1492,9 @@ static void ravb_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
static int ravb_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;

	if (wol->wolopts & ~WAKE_MAGIC)
	if (!info->magic_pkt || (wol->wolopts & ~WAKE_MAGIC))
		return -EOPNOTSUPP;

	priv->wol_enabled = !!(wol->wolopts & WAKE_MAGIC);
@@ -1403,6 +1548,7 @@ static int ravb_open(struct net_device *ndev)
	int error;

	napi_enable(&priv->napi[RAVB_BE]);
	if (info->nc_queue)
		napi_enable(&priv->napi[RAVB_NC]);

	if (!info->multi_irqs) {
@@ -1446,7 +1592,7 @@ static int ravb_open(struct net_device *ndev)
	ravb_emac_init(ndev);

	/* Initialise PTP Clock driver */
	if (info->no_ptp_cfg_active)
	if (info->gptp)
		ravb_ptp_init(ndev, priv->pdev);

	netif_tx_start_all_queues(ndev);
@@ -1460,7 +1606,7 @@ static int ravb_open(struct net_device *ndev)

out_ptp_stop:
	/* Stop PTP Clock driver */
	if (info->no_ptp_cfg_active)
	if (info->gptp)
		ravb_ptp_stop(ndev);
out_free_irq_nc_tx:
	if (!info->multi_irqs)
@@ -1477,6 +1623,7 @@ static int ravb_open(struct net_device *ndev)
out_free_irq:
	free_irq(ndev->irq, ndev);
out_napi_off:
	if (info->nc_queue)
		napi_disable(&priv->napi[RAVB_NC]);
	napi_disable(&priv->napi[RAVB_BE]);
	return error;
@@ -1508,7 +1655,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
	netif_tx_stop_all_queues(ndev);

	/* Stop PTP Clock driver */
	if (info->no_ptp_cfg_active)
	if (info->gptp)
		ravb_ptp_stop(ndev);

	/* Wait for DMA stopping */
@@ -1526,6 +1673,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
	}

	ravb_ring_free(ndev, RAVB_BE);
	if (info->nc_queue)
		ravb_ring_free(ndev, RAVB_NC);

	/* Device init */
@@ -1543,7 +1691,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)

out:
	/* Initialise PTP Clock driver */
	if (info->no_ptp_cfg_active)
	if (info->gptp)
		ravb_ptp_init(ndev, priv->pdev);

	netif_tx_start_all_queues(ndev);
@@ -1553,6 +1701,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	unsigned int num_tx_desc = priv->num_tx_desc;
	u16 q = skb_get_queue_mapping(skb);
	struct ravb_tstamp_skb *ts_skb;
@@ -1629,6 +1778,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
	desc->dptr = cpu_to_le32(dma_addr);

	/* TX timestamp required */
	if (info->gptp || info->ccc_gac) {
		if (q == RAVB_NC) {
			ts_skb = kmalloc(sizeof(*ts_skb), GFP_ATOMIC);
			if (!ts_skb) {
@@ -1651,6 +1801,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
		}

		skb_tx_timestamp(skb);
	}
	/* Descriptor type must be set after all the above writes */
	dma_wmb();
	if (num_tx_desc > 1) {
@@ -1698,28 +1849,38 @@ static struct net_device_stats *ravb_get_stats(struct net_device *ndev)

	nstats = &ndev->stats;
	stats0 = &priv->stats[RAVB_BE];
	stats1 = &priv->stats[RAVB_NC];

	if (info->tx_counters) {
		nstats->tx_dropped += ravb_read(ndev, TROCR);
		ravb_write(ndev, 0, TROCR);	/* (write clear) */
	}

	nstats->rx_packets = stats0->rx_packets + stats1->rx_packets;
	nstats->tx_packets = stats0->tx_packets + stats1->tx_packets;
	nstats->rx_bytes = stats0->rx_bytes + stats1->rx_bytes;
	nstats->tx_bytes = stats0->tx_bytes + stats1->tx_bytes;
	nstats->multicast = stats0->multicast + stats1->multicast;
	nstats->rx_errors = stats0->rx_errors + stats1->rx_errors;
	nstats->rx_crc_errors = stats0->rx_crc_errors + stats1->rx_crc_errors;
	nstats->rx_frame_errors =
		stats0->rx_frame_errors + stats1->rx_frame_errors;
	nstats->rx_length_errors =
		stats0->rx_length_errors + stats1->rx_length_errors;
	nstats->rx_missed_errors =
		stats0->rx_missed_errors + stats1->rx_missed_errors;
	nstats->rx_over_errors =
		stats0->rx_over_errors + stats1->rx_over_errors;
	nstats->rx_packets = stats0->rx_packets;
	nstats->tx_packets = stats0->tx_packets;
	nstats->rx_bytes = stats0->rx_bytes;
	nstats->tx_bytes = stats0->tx_bytes;
	nstats->multicast = stats0->multicast;
	nstats->rx_errors = stats0->rx_errors;
	nstats->rx_crc_errors = stats0->rx_crc_errors;
	nstats->rx_frame_errors = stats0->rx_frame_errors;
	nstats->rx_length_errors = stats0->rx_length_errors;
	nstats->rx_missed_errors = stats0->rx_missed_errors;
	nstats->rx_over_errors = stats0->rx_over_errors;
	if (info->nc_queue) {
		stats1 = &priv->stats[RAVB_NC];

		nstats->rx_packets += stats1->rx_packets;
		nstats->tx_packets += stats1->tx_packets;
		nstats->rx_bytes += stats1->rx_bytes;
		nstats->tx_bytes += stats1->tx_bytes;
		nstats->multicast += stats1->multicast;
		nstats->rx_errors += stats1->rx_errors;
		nstats->rx_crc_errors += stats1->rx_crc_errors;
		nstats->rx_frame_errors += stats1->rx_frame_errors;
		nstats->rx_length_errors += stats1->rx_length_errors;
		nstats->rx_missed_errors += stats1->rx_missed_errors;
		nstats->rx_over_errors += stats1->rx_over_errors;
	}

	return nstats;
}
@@ -1752,7 +1913,7 @@ static int ravb_close(struct net_device *ndev)
	ravb_write(ndev, 0, TIC);

	/* Stop PTP Clock driver */
	if (info->no_ptp_cfg_active)
	if (info->gptp)
		ravb_ptp_stop(ndev);

	/* Set the config mode to stop the AVB-DMAC's processes */
@@ -1761,11 +1922,13 @@ static int ravb_close(struct net_device *ndev)
			   "device will be stopped after h/w processes are done.\n");

	/* Clear the timestamp list */
	if (info->gptp || info->ccc_gac) {
		list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) {
			list_del(&ts_skb->list);
			kfree_skb(ts_skb->skb);
			kfree(ts_skb);
		}
	}

	/* PHY disconnect */
	if (ndev->phydev) {
@@ -1784,11 +1947,13 @@ static int ravb_close(struct net_device *ndev)
	}
	free_irq(ndev->irq, ndev);

	if (info->nc_queue)
		napi_disable(&priv->napi[RAVB_NC]);
	napi_disable(&priv->napi[RAVB_BE]);

	/* Free all the skb's in the RX queue and the DMA buffers. */
	ravb_ring_free(ndev, RAVB_BE);
	if (info->nc_queue)
		ravb_ring_free(ndev, RAVB_NC);

	return 0;
@@ -1918,7 +2083,14 @@ static void ravb_set_rx_csum(struct net_device *ndev, bool enable)
	spin_unlock_irqrestore(&priv->lock, flags);
}

static int ravb_set_features_rx_csum(struct net_device *ndev,
static int ravb_set_features_gbeth(struct net_device *ndev,
				   netdev_features_t features)
{
	/* Place holder */
	return 0;
}

static int ravb_set_features_rcar(struct net_device *ndev,
				  netdev_features_t features)
{
	netdev_features_t changed = ndev->features ^ features;
@@ -1937,7 +2109,7 @@ static int ravb_set_features(struct net_device *ndev,
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;

	return info->set_rx_csum_feature(ndev, features);
	return info->set_feature(ndev, features);
}

static const struct net_device_ops ravb_netdev_ops = {
@@ -2005,20 +2177,23 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
	.rx_ring_format = ravb_rx_ring_format,
	.alloc_rx_desc = ravb_alloc_rx_desc,
	.receive = ravb_rcar_rx,
	.set_rate = ravb_set_rate,
	.set_rx_csum_feature = ravb_set_features_rx_csum,
	.dmac_init = ravb_rcar_dmac_init,
	.emac_init = ravb_rcar_emac_init,
	.set_rate = ravb_set_rate_rcar,
	.set_feature = ravb_set_features_rcar,
	.dmac_init = ravb_dmac_init_rcar,
	.emac_init = ravb_emac_init_rcar,
	.gstrings_stats = ravb_gstrings_stats,
	.gstrings_size = sizeof(ravb_gstrings_stats),
	.net_hw_features = NETIF_F_RXCSUM,
	.net_features = NETIF_F_RXCSUM,
	.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
	.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
	.tsrq = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
	.internal_delay = 1,
	.tx_counters = 1,
	.multi_irqs = 1,
	.ptp_cfg_active = 1,
	.ccc_gac = 1,
	.nc_queue = 1,
	.magic_pkt = 1,
};

static const struct ravb_hw_info ravb_gen2_hw_info = {
@@ -2026,18 +2201,37 @@ static const struct ravb_hw_info ravb_gen2_hw_info = {
	.rx_ring_format = ravb_rx_ring_format,
	.alloc_rx_desc = ravb_alloc_rx_desc,
	.receive = ravb_rcar_rx,
	.set_rate = ravb_set_rate,
	.set_rx_csum_feature = ravb_set_features_rx_csum,
	.dmac_init = ravb_rcar_dmac_init,
	.emac_init = ravb_rcar_emac_init,
	.set_rate = ravb_set_rate_rcar,
	.set_feature = ravb_set_features_rcar,
	.dmac_init = ravb_dmac_init_rcar,
	.emac_init = ravb_emac_init_rcar,
	.gstrings_stats = ravb_gstrings_stats,
	.gstrings_size = sizeof(ravb_gstrings_stats),
	.net_hw_features = NETIF_F_RXCSUM,
	.net_features = NETIF_F_RXCSUM,
	.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
	.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
	.tsrq = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
	.aligned_tx = 1,
	.no_ptp_cfg_active = 1,
	.gptp = 1,
	.nc_queue = 1,
	.magic_pkt = 1,
};

static const struct ravb_hw_info gbeth_hw_info = {
	.rx_ring_free = ravb_rx_ring_free_gbeth,
	.rx_ring_format = ravb_rx_ring_format_gbeth,
	.alloc_rx_desc = ravb_alloc_rx_desc_gbeth,
	.receive = ravb_rx_gbeth,
	.set_rate = ravb_set_rate_gbeth,
	.set_feature = ravb_set_features_gbeth,
	.dmac_init = ravb_dmac_init_gbeth,
	.emac_init = ravb_emac_init_gbeth,
	.max_rx_len = GBETH_RX_BUFF_MAX + RAVB_ALIGN - 1,
	.tsrq = TCCR_TSRQ0,
	.aligned_tx = 1,
	.tx_counters = 1,
	.half_duplex = 1,
};

static const struct of_device_id ravb_match_table[] = {
@@ -2046,6 +2240,7 @@ static const struct of_device_id ravb_match_table[] = {
	{ .compatible = "renesas,etheravb-rcar-gen2", .data = &ravb_gen2_hw_info },
	{ .compatible = "renesas,etheravb-r8a7795", .data = &ravb_gen3_hw_info },
	{ .compatible = "renesas,etheravb-rcar-gen3", .data = &ravb_gen3_hw_info },
	{ .compatible = "renesas,rzg2l-gbeth", .data = &gbeth_hw_info },
	{ }
};
MODULE_DEVICE_TABLE(of, ravb_match_table);
@@ -2080,13 +2275,15 @@ static void ravb_set_config_mode(struct net_device *ndev)
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;

	if (info->no_ptp_cfg_active) {
	if (info->gptp) {
		ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG);
		/* Set CSEL value */
		ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB);
	} else {
	} else if (info->ccc_gac) {
		ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG |
			    CCC_GAC | CCC_CSEL_HPB);
	} else {
		ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG);
	}
}

@@ -2192,8 +2389,11 @@ static int ravb_probe(struct platform_device *pdev)
	priv->pdev = pdev;
	priv->num_tx_ring[RAVB_BE] = BE_TX_RING_SIZE;
	priv->num_rx_ring[RAVB_BE] = BE_RX_RING_SIZE;
	if (info->nc_queue) {
		priv->num_tx_ring[RAVB_NC] = NC_TX_RING_SIZE;
		priv->num_rx_ring[RAVB_NC] = NC_RX_RING_SIZE;
	}

	priv->addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(priv->addr)) {
		error = PTR_ERR(priv->addr);
@@ -2269,6 +2469,7 @@ static int ravb_probe(struct platform_device *pdev)
	/* Set AVB config mode */
	ravb_set_config_mode(ndev);

	if (info->gptp || info->ccc_gac) {
		/* Set GTI value */
		error = ravb_set_gti(ndev);
		if (error)
@@ -2276,6 +2477,7 @@ static int ravb_probe(struct platform_device *pdev)

		/* Request GTI loading */
		ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
	}

	if (info->internal_delay) {
		ravb_parse_delay_mode(np, ndev);
@@ -2301,7 +2503,7 @@ static int ravb_probe(struct platform_device *pdev)
	INIT_LIST_HEAD(&priv->ts_skb_list);

	/* Initialise PTP Clock driver */
	if (info->ptp_cfg_active)
	if (info->ccc_gac)
		ravb_ptp_init(ndev, pdev);

	/* Debug message level */
@@ -2323,6 +2525,7 @@ static int ravb_probe(struct platform_device *pdev)
	}

	netif_napi_add(ndev, &priv->napi[RAVB_BE], ravb_poll, 64);
	if (info->nc_queue)
		netif_napi_add(ndev, &priv->napi[RAVB_NC], ravb_poll, 64);

	/* Network device register */
@@ -2341,7 +2544,9 @@ static int ravb_probe(struct platform_device *pdev)
	return 0;

out_napi_del:
	if (info->nc_queue)
		netif_napi_del(&priv->napi[RAVB_NC]);

	netif_napi_del(&priv->napi[RAVB_BE]);
	ravb_mdio_release(priv);
out_dma_free:
@@ -2349,7 +2554,7 @@ static int ravb_probe(struct platform_device *pdev)
			  priv->desc_bat_dma);

	/* Stop PTP Clock driver */
	if (info->ptp_cfg_active)
	if (info->ccc_gac)
		ravb_ptp_stop(ndev);
out_disable_refclk:
	clk_disable_unprepare(priv->refclk);
@@ -2369,7 +2574,7 @@ static int ravb_remove(struct platform_device *pdev)
	const struct ravb_hw_info *info = priv->info;

	/* Stop PTP Clock driver */
	if (info->ptp_cfg_active)
	if (info->ccc_gac)
		ravb_ptp_stop(ndev);

	clk_disable_unprepare(priv->refclk);
@@ -2380,6 +2585,7 @@ static int ravb_remove(struct platform_device *pdev)
	ravb_write(ndev, CCC_OPC_RESET, CCC);
	pm_runtime_put_sync(&pdev->dev);
	unregister_netdev(ndev);
	if (info->nc_queue)
		netif_napi_del(&priv->napi[RAVB_NC]);
	netif_napi_del(&priv->napi[RAVB_BE]);
	ravb_mdio_release(priv);
@@ -2394,6 +2600,7 @@ static int ravb_remove(struct platform_device *pdev)
static int ravb_wol_setup(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;

	/* Disable interrupts by clearing the interrupt masks. */
	ravb_write(ndev, 0, RIC0);
@@ -2402,6 +2609,7 @@ static int ravb_wol_setup(struct net_device *ndev)

	/* Only allow ECI interrupts */
	synchronize_irq(priv->emac_irq);
	if (info->nc_queue)
		napi_disable(&priv->napi[RAVB_NC]);
	napi_disable(&priv->napi[RAVB_BE]);
	ravb_write(ndev, ECSIPR_MPDIP, ECSIPR);
@@ -2415,8 +2623,10 @@ static int ravb_wol_setup(struct net_device *ndev)
static int ravb_wol_restore(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	int ret;

	if (info->nc_queue)
		napi_enable(&priv->napi[RAVB_NC]);
	napi_enable(&priv->napi[RAVB_BE]);

@@ -2468,6 +2678,7 @@ static int __maybe_unused ravb_resume(struct device *dev)
	/* Set AVB config mode */
	ravb_set_config_mode(ndev);

	if (info->gptp || info->ccc_gac) {
		/* Set GTI value */
		ret = ravb_set_gti(ndev);
		if (ret)
@@ -2475,6 +2686,7 @@ static int __maybe_unused ravb_resume(struct device *dev)

		/* Request GTI loading */
		ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
	}

	if (info->internal_delay)
		ravb_set_delay_mode(ndev);