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

Merge branch 'ravb-gbit-refactor'

Biju Das says:

====================
Add Factorisation code to support Gigabit Ethernet driver

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 aims to add factorisation code to support RZ/G2L SoC,
hardware feature bits for gPTP feature, Multiple irq feature and
optional reset support.

Ref:-
 * https://lore.kernel.org/linux-renesas-soc/TYCPR01MB59334319695607A2683C1A5E86E59@TYCPR01MB5933.jpnprd01.prod.outlook.com/T/#t


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6956fa39 0d13a1a4
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -956,10 +956,6 @@ enum RAVB_QUEUE {

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

/* TX descriptors per packet */
#define NUM_TX_DESC_GEN2	2
#define NUM_TX_DESC_GEN3	1

struct ravb_tstamp_skb {
	struct list_head list;
	struct sk_buff *skb;
@@ -983,17 +979,19 @@ struct ravb_ptp {
	struct ravb_ptp_perout perout[N_PER_OUT];
};

enum ravb_chip_id {
	RCAR_GEN2,
	RCAR_GEN3,
};

struct ravb_hw_info {
	void (*rx_ring_free)(struct net_device *ndev, int q);
	void (*rx_ring_format)(struct net_device *ndev, int q);
	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);
	void (*emac_init)(struct net_device *ndev);
	const char (*gstrings_stats)[ETH_GSTRING_LEN];
	size_t gstrings_size;
	netdev_features_t net_hw_features;
	netdev_features_t net_features;
	enum ravb_chip_id chip_id;
	int stats_len;
	size_t max_rx_len;
	unsigned aligned_tx: 1;
@@ -1001,6 +999,9 @@ struct ravb_hw_info {
	/* 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 */
};

struct ravb_private {
@@ -1044,7 +1045,6 @@ struct ravb_private {
	int msg_enable;
	int speed;
	int emac_irq;
	enum ravb_chip_id chip_id;
	int rx_irqs[NUM_RX_QUEUE];
	int tx_irqs[NUM_TX_QUEUE];

@@ -1057,6 +1057,7 @@ struct ravb_private {
	unsigned int num_tx_desc;	/* TX descriptors per packet */

	const struct ravb_hw_info *info;
	struct reset_control *rstc;
};

static inline u32 ravb_read(struct net_device *ndev, enum ravb_reg reg)
+187 −85
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/sys_soc.h>
#include <linux/reset.h>

#include <asm/div64.h>

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

/* Free skb's and DMA buffers for Ethernet AVB */
static void ravb_ring_free(struct net_device *ndev, int q)
static void ravb_rx_ring_free(struct net_device *ndev, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
	unsigned int num_tx_desc = priv->num_tx_desc;
	unsigned int ring_size;
	unsigned int i;

	if (priv->rx_ring[q]) {
	if (!priv->rx_ring[q])
		return;

	for (i = 0; i < priv->num_rx_ring[q]; i++) {
		struct ravb_ex_rx_desc *desc = &priv->rx_ring[q][i];

@@ -242,6 +243,17 @@ static void ravb_ring_free(struct net_device *ndev, int q)
	priv->rx_ring[q] = NULL;
}

/* Free skb's and DMA buffers for Ethernet AVB */
static void ravb_ring_free(struct net_device *ndev, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	unsigned int num_tx_desc = priv->num_tx_desc;
	unsigned int ring_size;
	unsigned int i;

	info->rx_ring_free(ndev, q);

	if (priv->tx_ring[q]) {
		ravb_tx_free(ndev, q, false);

@@ -271,25 +283,14 @@ static void ravb_ring_free(struct net_device *ndev, int q)
	priv->tx_skb[q] = NULL;
}

/* Format skb and descriptor buffer for Ethernet AVB */
static void ravb_ring_format(struct net_device *ndev, int q)
static void ravb_rx_ring_format(struct net_device *ndev, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
	unsigned int num_tx_desc = priv->num_tx_desc;
	struct ravb_ex_rx_desc *rx_desc;
	struct ravb_tx_desc *tx_desc;
	struct ravb_desc *desc;
	unsigned int rx_ring_size = sizeof(*rx_desc) * priv->num_rx_ring[q];
	unsigned int tx_ring_size = sizeof(*tx_desc) * priv->num_tx_ring[q] *
				    num_tx_desc;
	dma_addr_t dma_addr;
	unsigned int i;

	priv->cur_rx[q] = 0;
	priv->cur_tx[q] = 0;
	priv->dirty_rx[q] = 0;
	priv->dirty_tx[q] = 0;

	memset(priv->rx_ring[q], 0, rx_ring_size);
	/* Build RX ring buffer */
	for (i = 0; i < priv->num_rx_ring[q]; i++) {
@@ -310,6 +311,26 @@ static void ravb_ring_format(struct net_device *ndev, int q)
	rx_desc = &priv->rx_ring[q][i];
	rx_desc->dptr = cpu_to_le32((u32)priv->rx_desc_dma[q]);
	rx_desc->die_dt = DT_LINKFIX; /* type */
}

/* Format skb and descriptor buffer for Ethernet AVB */
static void ravb_ring_format(struct net_device *ndev, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	unsigned int num_tx_desc = priv->num_tx_desc;
	struct ravb_tx_desc *tx_desc;
	struct ravb_desc *desc;
	unsigned int tx_ring_size = sizeof(*tx_desc) * priv->num_tx_ring[q] *
				    num_tx_desc;
	unsigned int i;

	priv->cur_rx[q] = 0;
	priv->cur_tx[q] = 0;
	priv->dirty_rx[q] = 0;
	priv->dirty_tx[q] = 0;

	info->rx_ring_format(ndev, q);

	memset(priv->tx_ring[q], 0, tx_ring_size);
	/* Build TX ring buffer */
@@ -335,6 +356,19 @@ 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(struct net_device *ndev, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
	unsigned int ring_size;

	ring_size = sizeof(struct ravb_ex_rx_desc) * (priv->num_rx_ring[q] + 1);

	priv->rx_ring[q] = dma_alloc_coherent(ndev->dev.parent, ring_size,
					      &priv->rx_desc_dma[q],
					      GFP_KERNEL);
	return priv->rx_ring[q];
}

/* Init skb and descriptor buffer for Ethernet AVB */
static int ravb_ring_init(struct net_device *ndev, int q)
{
@@ -370,11 +404,7 @@ static int ravb_ring_init(struct net_device *ndev, int q)
	}

	/* Allocate all RX descriptors. */
	ring_size = sizeof(struct ravb_ex_rx_desc) * (priv->num_rx_ring[q] + 1);
	priv->rx_ring[q] = dma_alloc_coherent(ndev->dev.parent, ring_size,
					      &priv->rx_desc_dma[q],
					      GFP_KERNEL);
	if (!priv->rx_ring[q])
	if (!info->alloc_rx_desc(ndev, q))
		goto error;

	priv->dirty_rx[q] = 0;
@@ -396,8 +426,7 @@ static int ravb_ring_init(struct net_device *ndev, int q)
	return -ENOMEM;
}

/* E-MAC init function */
static void ravb_emac_init(struct net_device *ndev)
static void ravb_rcar_emac_init(struct net_device *ndev)
{
	/* Receive frame limit set register */
	ravb_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN, RFLR);
@@ -423,29 +452,19 @@ static void ravb_emac_init(struct net_device *ndev)
	ravb_write(ndev, ECSIPR_ICDIP | ECSIPR_MPDIP | ECSIPR_LCHNGIP, ECSIPR);
}

/* Device init function for Ethernet AVB */
static int ravb_dmac_init(struct net_device *ndev)
/* E-MAC init function */
static void ravb_emac_init(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	int error;

	/* Set CONFIG mode */
	error = ravb_config(ndev);
	if (error)
		return error;
	const struct ravb_hw_info *info = priv->info;

	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;
	info->emac_init(ndev);
}

	/* Descriptor format */
	ravb_ring_format(ndev, RAVB_BE);
	ravb_ring_format(ndev, RAVB_NC);
static void ravb_rcar_dmac_init(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;

	/* Set AVB RX */
	ravb_write(ndev,
@@ -458,7 +477,7 @@ static int ravb_dmac_init(struct net_device *ndev)
	ravb_write(ndev, TCCR_TFEN, TCCR);

	/* Interrupt init: */
	if (priv->chip_id == RCAR_GEN3) {
	if (info->multi_irqs) {
		/* Clear DIL.DPLx */
		ravb_write(ndev, 0, DIL);
		/* Set queue specific interrupt */
@@ -472,6 +491,34 @@ static int ravb_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);
}

/* Device init function for Ethernet AVB */
static int ravb_dmac_init(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	int error;

	/* Set CONFIG mode */
	error = ravb_config(ndev);
	if (error)
		return 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);

	info->dmac_init(ndev);

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

/* Packet receive function for Ethernet AVB */
static bool ravb_rx(struct net_device *ndev, int *quota, int q)
static bool ravb_rcar_rx(struct net_device *ndev, int *quota, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
@@ -647,6 +693,15 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q)
	return boguscnt <= 0;
}

/* Packet receive function for Ethernet AVB */
static bool ravb_rx(struct net_device *ndev, int *quota, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;

	return info->receive(ndev, quota, q);
}

static void ravb_rcv_snd_disable(struct net_device *ndev)
{
	/* Disable TX and RX */
@@ -758,6 +813,7 @@ static void ravb_error_interrupt(struct net_device *ndev)
static bool ravb_queue_interrupt(struct net_device *ndev, int q)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	u32 ris0 = ravb_read(ndev, RIS0);
	u32 ric0 = ravb_read(ndev, RIC0);
	u32 tis  = ravb_read(ndev, TIS);
@@ -766,7 +822,7 @@ static bool ravb_queue_interrupt(struct net_device *ndev, int q)
	if (((ris0 & ric0) & BIT(q)) || ((tis  & tic)  & BIT(q))) {
		if (napi_schedule_prep(&priv->napi[q])) {
			/* Mask RX and TX interrupts */
			if (priv->chip_id == RCAR_GEN2) {
			if (!info->multi_irqs) {
				ravb_write(ndev, ric0 & ~BIT(q), RIC0);
				ravb_write(ndev, tic & ~BIT(q), TIC);
			} else {
@@ -909,6 +965,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)
{
	struct net_device *ndev = napi->dev;
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	unsigned long flags;
	int q = napi - priv->napi;
	int mask = BIT(q);
@@ -932,7 +989,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)

	/* Re-enable RX/TX interrupts */
	spin_lock_irqsave(&priv->lock, flags);
	if (priv->chip_id == RCAR_GEN2) {
	if (!info->multi_irqs) {
		ravb_modify(ndev, RIC0, mask, mask);
		ravb_modify(ndev, TIC,  mask, mask);
	} else {
@@ -956,6 +1013,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)
static void ravb_adjust_link(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	struct phy_device *phydev = ndev->phydev;
	bool new_state = false;
	unsigned long flags;
@@ -970,7 +1028,7 @@ static void ravb_adjust_link(struct net_device *ndev)
		if (phydev->speed != priv->speed) {
			new_state = true;
			priv->speed = phydev->speed;
			ravb_set_rate(ndev);
			info->set_rate(ndev);
		}
		if (!priv->link) {
			ravb_modify(ndev, ECMR, ECMR_TXF, 0);
@@ -1202,6 +1260,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
			      struct ethtool_ringparam *ring)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	int error;

	if (ring->tx_pending > BE_TX_RING_MAX ||
@@ -1215,7 +1274,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
	if (netif_running(ndev)) {
		netif_device_detach(ndev);
		/* Stop PTP Clock driver */
		if (priv->chip_id == RCAR_GEN2)
		if (info->no_ptp_cfg_active)
			ravb_ptp_stop(ndev);
		/* Wait for DMA stopping */
		error = ravb_stop_dma(ndev);
@@ -1247,7 +1306,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
		ravb_emac_init(ndev);

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

		netif_device_attach(ndev);
@@ -1338,6 +1397,7 @@ static inline int ravb_hook_irq(unsigned int irq, irq_handler_t handler,
static int ravb_open(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	struct platform_device *pdev = priv->pdev;
	struct device *dev = &pdev->dev;
	int error;
@@ -1345,7 +1405,7 @@ static int ravb_open(struct net_device *ndev)
	napi_enable(&priv->napi[RAVB_BE]);
	napi_enable(&priv->napi[RAVB_NC]);

	if (priv->chip_id == RCAR_GEN2) {
	if (!info->multi_irqs) {
		error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED,
				    ndev->name, ndev);
		if (error) {
@@ -1386,7 +1446,7 @@ static int ravb_open(struct net_device *ndev)
	ravb_emac_init(ndev);

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

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

out_ptp_stop:
	/* Stop PTP Clock driver */
	if (priv->chip_id == RCAR_GEN2)
	if (info->no_ptp_cfg_active)
		ravb_ptp_stop(ndev);
out_free_irq_nc_tx:
	if (priv->chip_id == RCAR_GEN2)
	if (!info->multi_irqs)
		goto out_free_irq;
	free_irq(priv->tx_irqs[RAVB_NC], ndev);
out_free_irq_nc_rx:
@@ -1441,13 +1501,14 @@ static void ravb_tx_timeout_work(struct work_struct *work)
{
	struct ravb_private *priv = container_of(work, struct ravb_private,
						 work);
	const struct ravb_hw_info *info = priv->info;
	struct net_device *ndev = priv->ndev;
	int error;

	netif_tx_stop_all_queues(ndev);

	/* Stop PTP Clock driver */
	if (priv->chip_id == RCAR_GEN2)
	if (info->no_ptp_cfg_active)
		ravb_ptp_stop(ndev);

	/* Wait for DMA stopping */
@@ -1482,7 +1543,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)

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

	netif_tx_start_all_queues(ndev);
@@ -1680,6 +1741,7 @@ static int ravb_close(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 ravb_tstamp_skb *ts_skb, *ts_skb2;

	netif_tx_stop_all_queues(ndev);
@@ -1690,7 +1752,7 @@ static int ravb_close(struct net_device *ndev)
	ravb_write(ndev, 0, TIC);

	/* Stop PTP Clock driver */
	if (priv->chip_id == RCAR_GEN2)
	if (info->no_ptp_cfg_active)
		ravb_ptp_stop(ndev);

	/* Set the config mode to stop the AVB-DMAC's processes */
@@ -1713,7 +1775,7 @@ static int ravb_close(struct net_device *ndev)
			of_phy_deregister_fixed_link(np);
	}

	if (priv->chip_id != RCAR_GEN2) {
	if (info->multi_irqs) {
		free_irq(priv->tx_irqs[RAVB_NC], ndev);
		free_irq(priv->rx_irqs[RAVB_NC], ndev);
		free_irq(priv->tx_irqs[RAVB_BE], ndev);
@@ -1856,7 +1918,7 @@ static void ravb_set_rx_csum(struct net_device *ndev, bool enable)
	spin_unlock_irqrestore(&priv->lock, flags);
}

static int ravb_set_features(struct net_device *ndev,
static int ravb_set_features_rx_csum(struct net_device *ndev,
				     netdev_features_t features)
{
	netdev_features_t changed = ndev->features ^ features;
@@ -1869,6 +1931,15 @@ static int ravb_set_features(struct net_device *ndev,
	return 0;
}

static int ravb_set_features(struct net_device *ndev,
			     netdev_features_t features)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;

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

static const struct net_device_ops ravb_netdev_ops = {
	.ndo_open		= ravb_open,
	.ndo_stop		= ravb_close,
@@ -1930,26 +2001,43 @@ static int ravb_mdio_release(struct ravb_private *priv)
}

static const struct ravb_hw_info ravb_gen3_hw_info = {
	.rx_ring_free = ravb_rx_ring_free,
	.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,
	.gstrings_stats = ravb_gstrings_stats,
	.gstrings_size = sizeof(ravb_gstrings_stats),
	.net_hw_features = NETIF_F_RXCSUM,
	.net_features = NETIF_F_RXCSUM,
	.chip_id = RCAR_GEN3,
	.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
	.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
	.internal_delay = 1,
	.tx_counters = 1,
	.multi_irqs = 1,
	.ptp_cfg_active = 1,
};

static const struct ravb_hw_info ravb_gen2_hw_info = {
	.rx_ring_free = ravb_rx_ring_free,
	.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,
	.gstrings_stats = ravb_gstrings_stats,
	.gstrings_size = sizeof(ravb_gstrings_stats),
	.net_hw_features = NETIF_F_RXCSUM,
	.net_features = NETIF_F_RXCSUM,
	.chip_id = RCAR_GEN2,
	.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
	.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
	.aligned_tx = 1,
	.no_ptp_cfg_active = 1,
};

static const struct of_device_id ravb_match_table[] = {
@@ -1990,8 +2078,9 @@ static int ravb_set_gti(struct net_device *ndev)
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 (priv->chip_id == RCAR_GEN2) {
	if (info->no_ptp_cfg_active) {
		ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG);
		/* Set CSEL value */
		ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB);
@@ -2052,6 +2141,7 @@ static int ravb_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	const struct ravb_hw_info *info;
	struct reset_control *rstc;
	struct ravb_private *priv;
	struct net_device *ndev;
	int error, irq, q;
@@ -2064,6 +2154,11 @@ static int ravb_probe(struct platform_device *pdev)
		return -EINVAL;
	}

	rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
	if (IS_ERR(rstc))
		return dev_err_probe(&pdev->dev, PTR_ERR(rstc),
				     "failed to get cpg reset\n");

	ndev = alloc_etherdev_mqs(sizeof(struct ravb_private),
				  NUM_TX_QUEUE, NUM_RX_QUEUE);
	if (!ndev)
@@ -2074,10 +2169,11 @@ static int ravb_probe(struct platform_device *pdev)
	ndev->features = info->net_features;
	ndev->hw_features = info->net_hw_features;

	reset_control_deassert(rstc);
	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);

	if (info->chip_id == RCAR_GEN3)
	if (info->multi_irqs)
		irq = platform_get_irq_byname(pdev, "ch22");
	else
		irq = platform_get_irq(pdev, 0);
@@ -2091,6 +2187,7 @@ static int ravb_probe(struct platform_device *pdev)

	priv = netdev_priv(ndev);
	priv->info = info;
	priv->rstc = rstc;
	priv->ndev = ndev;
	priv->pdev = pdev;
	priv->num_tx_ring[RAVB_BE] = BE_TX_RING_SIZE;
@@ -2117,7 +2214,7 @@ static int ravb_probe(struct platform_device *pdev)
	priv->avb_link_active_low =
		of_property_read_bool(np, "renesas,ether-link-active-low");

	if (info->chip_id == RCAR_GEN3) {
	if (info->multi_irqs) {
		irq = platform_get_irq_byname(pdev, "ch24");
		if (irq < 0) {
			error = irq;
@@ -2142,8 +2239,6 @@ static int ravb_probe(struct platform_device *pdev)
		}
	}

	priv->chip_id = info->chip_id;

	priv->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(priv->clk)) {
		error = PTR_ERR(priv->clk);
@@ -2160,8 +2255,12 @@ static int ravb_probe(struct platform_device *pdev)
	ndev->max_mtu = 2048 - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
	ndev->min_mtu = ETH_MIN_MTU;

	priv->num_tx_desc = info->aligned_tx ?
		NUM_TX_DESC_GEN2 : NUM_TX_DESC_GEN3;
	/* FIXME: R-Car Gen2 has 4byte alignment restriction for tx buffer
	 * Use two descriptor to handle such situation. First descriptor to
	 * handle aligned data buffer and second descriptor to handle the
	 * overflow data because of alignment.
	 */
	priv->num_tx_desc = info->aligned_tx ? 2 : 1;

	/* Set function */
	ndev->netdev_ops = &ravb_netdev_ops;
@@ -2202,7 +2301,7 @@ static int ravb_probe(struct platform_device *pdev)
	INIT_LIST_HEAD(&priv->ts_skb_list);

	/* Initialise PTP Clock driver */
	if (info->chip_id != RCAR_GEN2)
	if (info->ptp_cfg_active)
		ravb_ptp_init(ndev, pdev);

	/* Debug message level */
@@ -2250,7 +2349,7 @@ static int ravb_probe(struct platform_device *pdev)
			  priv->desc_bat_dma);

	/* Stop PTP Clock driver */
	if (info->chip_id != RCAR_GEN2)
	if (info->ptp_cfg_active)
		ravb_ptp_stop(ndev);
out_disable_refclk:
	clk_disable_unprepare(priv->refclk);
@@ -2259,6 +2358,7 @@ static int ravb_probe(struct platform_device *pdev)

	pm_runtime_put(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
	reset_control_assert(rstc);
	return error;
}

@@ -2266,9 +2366,10 @@ static int ravb_remove(struct platform_device *pdev)
{
	struct net_device *ndev = platform_get_drvdata(pdev);
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;

	/* Stop PTP Clock driver */
	if (priv->chip_id != RCAR_GEN2)
	if (info->ptp_cfg_active)
		ravb_ptp_stop(ndev);

	clk_disable_unprepare(priv->refclk);
@@ -2283,6 +2384,7 @@ static int ravb_remove(struct platform_device *pdev)
	netif_napi_del(&priv->napi[RAVB_BE]);
	ravb_mdio_release(priv);
	pm_runtime_disable(&pdev->dev);
	reset_control_assert(priv->rstc);
	free_netdev(ndev);
	platform_set_drvdata(pdev, NULL);

+5 −3
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
{
	struct ravb_private *priv = container_of(ptp, struct ravb_private,
						 ptp.info);
	const struct ravb_hw_info *info = priv->info;
	struct net_device *ndev = priv->ndev;
	unsigned long flags;

@@ -197,7 +198,7 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
	priv->ptp.extts[req->index] = on;

	spin_lock_irqsave(&priv->lock, flags);
	if (priv->chip_id == RCAR_GEN2)
	if (!info->multi_irqs)
		ravb_modify(ndev, GIC, GIC_PTCE, on ? GIC_PTCE : 0);
	else if (on)
		ravb_write(ndev, GIE_PTCS, GIE);
@@ -213,6 +214,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
{
	struct ravb_private *priv = container_of(ptp, struct ravb_private,
						 ptp.info);
	const struct ravb_hw_info *info = priv->info;
	struct net_device *ndev = priv->ndev;
	struct ravb_ptp_perout *perout;
	unsigned long flags;
@@ -252,7 +254,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
		error = ravb_ptp_update_compare(priv, (u32)start_ns);
		if (!error) {
			/* Unmask interrupt */
			if (priv->chip_id == RCAR_GEN2)
			if (!info->multi_irqs)
				ravb_modify(ndev, GIC, GIC_PTME, GIC_PTME);
			else
				ravb_write(ndev, GIE_PTMS0, GIE);
@@ -264,7 +266,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
		perout->period = 0;

		/* Mask interrupt */
		if (priv->chip_id == RCAR_GEN2)
		if (!info->multi_irqs)
			ravb_modify(ndev, GIC, GIC_PTME, 0);
		else
			ravb_write(ndev, GID_PTMD0, GID);