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

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
......@@ -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)
......
......@@ -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,31 +217,42 @@ static int ravb_tx_free(struct net_device *ndev, int q, bool free_txed_only)
return free_num;
}
static void ravb_rx_ring_free(struct net_device *ndev, int q)
{
struct ravb_private *priv = netdev_priv(ndev);
unsigned int ring_size;
unsigned int i;
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];
if (!dma_mapping_error(ndev->dev.parent,
le32_to_cpu(desc->dptr)))
dma_unmap_single(ndev->dev.parent,
le32_to_cpu(desc->dptr),
RX_BUF_SZ,
DMA_FROM_DEVICE);
}
ring_size = sizeof(struct ravb_ex_rx_desc) *
(priv->num_rx_ring[q] + 1);
dma_free_coherent(ndev->dev.parent, ring_size, priv->rx_ring[q],
priv->rx_desc_dma[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;
if (priv->rx_ring[q]) {
for (i = 0; i < priv->num_rx_ring[q]; i++) {
struct ravb_ex_rx_desc *desc = &priv->rx_ring[q][i];
if (!dma_mapping_error(ndev->dev.parent,
le32_to_cpu(desc->dptr)))
dma_unmap_single(ndev->dev.parent,
le32_to_cpu(desc->dptr),
RX_BUF_SZ,
DMA_FROM_DEVICE);
}
ring_size = sizeof(struct ravb_ex_rx_desc) *
(priv->num_rx_ring[q] + 1);
dma_free_coherent(ndev->dev.parent, ring_size, priv->rx_ring[q],
priv->rx_desc_dma[q]);
priv->rx_ring[q] = NULL;
}
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,8 +1918,8 @@ 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,
netdev_features_t features)
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);
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment