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 { ...@@ -956,10 +956,6 @@ enum RAVB_QUEUE {
#define RX_BUF_SZ (2048 - ETH_FCS_LEN + sizeof(__sum16)) #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 ravb_tstamp_skb {
struct list_head list; struct list_head list;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -983,17 +979,19 @@ struct ravb_ptp { ...@@ -983,17 +979,19 @@ struct ravb_ptp {
struct ravb_ptp_perout perout[N_PER_OUT]; struct ravb_ptp_perout perout[N_PER_OUT];
}; };
enum ravb_chip_id {
RCAR_GEN2,
RCAR_GEN3,
};
struct ravb_hw_info { 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]; const char (*gstrings_stats)[ETH_GSTRING_LEN];
size_t gstrings_size; size_t gstrings_size;
netdev_features_t net_hw_features; netdev_features_t net_hw_features;
netdev_features_t net_features; netdev_features_t net_features;
enum ravb_chip_id chip_id;
int stats_len; int stats_len;
size_t max_rx_len; size_t max_rx_len;
unsigned aligned_tx: 1; unsigned aligned_tx: 1;
...@@ -1001,6 +999,9 @@ struct ravb_hw_info { ...@@ -1001,6 +999,9 @@ struct ravb_hw_info {
/* hardware features */ /* hardware features */
unsigned internal_delay:1; /* AVB-DMAC has internal delays */ unsigned internal_delay:1; /* AVB-DMAC has internal delays */
unsigned tx_counters:1; /* E-MAC has TX counters */ 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 { struct ravb_private {
...@@ -1044,7 +1045,6 @@ struct ravb_private { ...@@ -1044,7 +1045,6 @@ struct ravb_private {
int msg_enable; int msg_enable;
int speed; int speed;
int emac_irq; int emac_irq;
enum ravb_chip_id chip_id;
int rx_irqs[NUM_RX_QUEUE]; int rx_irqs[NUM_RX_QUEUE];
int tx_irqs[NUM_TX_QUEUE]; int tx_irqs[NUM_TX_QUEUE];
...@@ -1057,6 +1057,7 @@ struct ravb_private { ...@@ -1057,6 +1057,7 @@ struct ravb_private {
unsigned int num_tx_desc; /* TX descriptors per packet */ unsigned int num_tx_desc; /* TX descriptors per packet */
const struct ravb_hw_info *info; const struct ravb_hw_info *info;
struct reset_control *rstc;
}; };
static inline u32 ravb_read(struct net_device *ndev, enum ravb_reg reg) static inline u32 ravb_read(struct net_device *ndev, enum ravb_reg reg)
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/sys_soc.h> #include <linux/sys_soc.h>
#include <linux/reset.h>
#include <asm/div64.h> #include <asm/div64.h>
...@@ -216,15 +217,15 @@ static int ravb_tx_free(struct net_device *ndev, int q, bool free_txed_only) ...@@ -216,15 +217,15 @@ static int ravb_tx_free(struct net_device *ndev, int q, bool free_txed_only)
return free_num; return free_num;
} }
/* Free skb's and DMA buffers for Ethernet AVB */ static void ravb_rx_ring_free(struct net_device *ndev, int q)
static void ravb_ring_free(struct net_device *ndev, int q)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
unsigned int num_tx_desc = priv->num_tx_desc;
unsigned int ring_size; unsigned int ring_size;
unsigned int i; unsigned int i;
if (priv->rx_ring[q]) { if (!priv->rx_ring[q])
return;
for (i = 0; i < priv->num_rx_ring[q]; i++) { for (i = 0; i < priv->num_rx_ring[q]; i++) {
struct ravb_ex_rx_desc *desc = &priv->rx_ring[q][i]; struct ravb_ex_rx_desc *desc = &priv->rx_ring[q][i];
...@@ -240,7 +241,18 @@ static void ravb_ring_free(struct net_device *ndev, int q) ...@@ -240,7 +241,18 @@ static void ravb_ring_free(struct net_device *ndev, int q)
dma_free_coherent(ndev->dev.parent, ring_size, priv->rx_ring[q], dma_free_coherent(ndev->dev.parent, ring_size, priv->rx_ring[q],
priv->rx_desc_dma[q]); priv->rx_desc_dma[q]);
priv->rx_ring[q] = NULL; 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]) { if (priv->tx_ring[q]) {
ravb_tx_free(ndev, q, false); ravb_tx_free(ndev, q, false);
...@@ -271,25 +283,14 @@ static void ravb_ring_free(struct net_device *ndev, int q) ...@@ -271,25 +283,14 @@ static void ravb_ring_free(struct net_device *ndev, int q)
priv->tx_skb[q] = NULL; priv->tx_skb[q] = NULL;
} }
/* Format skb and descriptor buffer for Ethernet AVB */ static void ravb_rx_ring_format(struct net_device *ndev, int q)
static void ravb_ring_format(struct net_device *ndev, int q)
{ {
struct ravb_private *priv = netdev_priv(ndev); 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_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 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; dma_addr_t dma_addr;
unsigned int i; 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); memset(priv->rx_ring[q], 0, rx_ring_size);
/* Build RX ring buffer */ /* Build RX ring buffer */
for (i = 0; i < priv->num_rx_ring[q]; i++) { 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) ...@@ -310,6 +311,26 @@ static void ravb_ring_format(struct net_device *ndev, int q)
rx_desc = &priv->rx_ring[q][i]; rx_desc = &priv->rx_ring[q][i];
rx_desc->dptr = cpu_to_le32((u32)priv->rx_desc_dma[q]); rx_desc->dptr = cpu_to_le32((u32)priv->rx_desc_dma[q]);
rx_desc->die_dt = DT_LINKFIX; /* type */ 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); memset(priv->tx_ring[q], 0, tx_ring_size);
/* Build TX ring buffer */ /* Build TX ring buffer */
...@@ -335,6 +356,19 @@ static void ravb_ring_format(struct net_device *ndev, int q) ...@@ -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]); 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 */ /* Init skb and descriptor buffer for Ethernet AVB */
static int ravb_ring_init(struct net_device *ndev, int q) 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) ...@@ -370,11 +404,7 @@ static int ravb_ring_init(struct net_device *ndev, int q)
} }
/* Allocate all RX descriptors. */ /* Allocate all RX descriptors. */
ring_size = sizeof(struct ravb_ex_rx_desc) * (priv->num_rx_ring[q] + 1); if (!info->alloc_rx_desc(ndev, q))
priv->rx_ring[q] = dma_alloc_coherent(ndev->dev.parent, ring_size,
&priv->rx_desc_dma[q],
GFP_KERNEL);
if (!priv->rx_ring[q])
goto error; goto error;
priv->dirty_rx[q] = 0; priv->dirty_rx[q] = 0;
...@@ -396,8 +426,7 @@ static int ravb_ring_init(struct net_device *ndev, int q) ...@@ -396,8 +426,7 @@ static int ravb_ring_init(struct net_device *ndev, int q)
return -ENOMEM; return -ENOMEM;
} }
/* E-MAC init function */ static void ravb_rcar_emac_init(struct net_device *ndev)
static void ravb_emac_init(struct net_device *ndev)
{ {
/* Receive frame limit set register */ /* Receive frame limit set register */
ravb_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN, RFLR); 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) ...@@ -423,29 +452,19 @@ static void ravb_emac_init(struct net_device *ndev)
ravb_write(ndev, ECSIPR_ICDIP | ECSIPR_MPDIP | ECSIPR_LCHNGIP, ECSIPR); ravb_write(ndev, ECSIPR_ICDIP | ECSIPR_MPDIP | ECSIPR_LCHNGIP, ECSIPR);
} }
/* Device init function for Ethernet AVB */ /* E-MAC init function */
static int ravb_dmac_init(struct net_device *ndev) static void ravb_emac_init(struct net_device *ndev)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
int error; const struct ravb_hw_info *info = priv->info;
/* Set CONFIG mode */
error = ravb_config(ndev);
if (error)
return error;
error = ravb_ring_init(ndev, RAVB_BE); info->emac_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 */ static void ravb_rcar_dmac_init(struct net_device *ndev)
ravb_ring_format(ndev, RAVB_BE); {
ravb_ring_format(ndev, RAVB_NC); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
/* Set AVB RX */ /* Set AVB RX */
ravb_write(ndev, ravb_write(ndev,
...@@ -458,7 +477,7 @@ static int ravb_dmac_init(struct net_device *ndev) ...@@ -458,7 +477,7 @@ static int ravb_dmac_init(struct net_device *ndev)
ravb_write(ndev, TCCR_TFEN, TCCR); ravb_write(ndev, TCCR_TFEN, TCCR);
/* Interrupt init: */ /* Interrupt init: */
if (priv->chip_id == RCAR_GEN3) { if (info->multi_irqs) {
/* Clear DIL.DPLx */ /* Clear DIL.DPLx */
ravb_write(ndev, 0, DIL); ravb_write(ndev, 0, DIL);
/* Set queue specific interrupt */ /* Set queue specific interrupt */
...@@ -472,6 +491,34 @@ static int ravb_dmac_init(struct net_device *ndev) ...@@ -472,6 +491,34 @@ static int ravb_dmac_init(struct net_device *ndev)
ravb_write(ndev, RIC2_QFE0 | RIC2_QFE1 | RIC2_RFFE, RIC2); ravb_write(ndev, RIC2_QFE0 | RIC2_QFE1 | RIC2_RFFE, RIC2);
/* Frame transmitted, timestamp FIFO updated */ /* Frame transmitted, timestamp FIFO updated */
ravb_write(ndev, TIC_FTE0 | TIC_FTE1 | TIC_TFUE, TIC); 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. */ /* Setting the control will start the AVB-DMAC process. */
ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_OPERATION); ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_OPERATION);
...@@ -532,8 +579,7 @@ static void ravb_rx_csum(struct sk_buff *skb) ...@@ -532,8 +579,7 @@ static void ravb_rx_csum(struct sk_buff *skb)
skb_trim(skb, skb->len - sizeof(__sum16)); skb_trim(skb, skb->len - sizeof(__sum16));
} }
/* Packet receive function for Ethernet AVB */ static bool ravb_rcar_rx(struct net_device *ndev, int *quota, int q)
static bool ravb_rx(struct net_device *ndev, int *quota, int q)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info; const struct ravb_hw_info *info = priv->info;
...@@ -647,6 +693,15 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q) ...@@ -647,6 +693,15 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q)
return boguscnt <= 0; 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) static void ravb_rcv_snd_disable(struct net_device *ndev)
{ {
/* Disable TX and RX */ /* Disable TX and RX */
...@@ -758,6 +813,7 @@ static void ravb_error_interrupt(struct net_device *ndev) ...@@ -758,6 +813,7 @@ static void ravb_error_interrupt(struct net_device *ndev)
static bool ravb_queue_interrupt(struct net_device *ndev, int q) static bool ravb_queue_interrupt(struct net_device *ndev, int q)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
u32 ris0 = ravb_read(ndev, RIS0); u32 ris0 = ravb_read(ndev, RIS0);
u32 ric0 = ravb_read(ndev, RIC0); u32 ric0 = ravb_read(ndev, RIC0);
u32 tis = ravb_read(ndev, TIS); u32 tis = ravb_read(ndev, TIS);
...@@ -766,7 +822,7 @@ static bool ravb_queue_interrupt(struct net_device *ndev, int q) ...@@ -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 (((ris0 & ric0) & BIT(q)) || ((tis & tic) & BIT(q))) {
if (napi_schedule_prep(&priv->napi[q])) { if (napi_schedule_prep(&priv->napi[q])) {
/* Mask RX and TX interrupts */ /* 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, ric0 & ~BIT(q), RIC0);
ravb_write(ndev, tic & ~BIT(q), TIC); ravb_write(ndev, tic & ~BIT(q), TIC);
} else { } else {
...@@ -909,6 +965,7 @@ static int ravb_poll(struct napi_struct *napi, int budget) ...@@ -909,6 +965,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)
{ {
struct net_device *ndev = napi->dev; struct net_device *ndev = napi->dev;
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
unsigned long flags; unsigned long flags;
int q = napi - priv->napi; int q = napi - priv->napi;
int mask = BIT(q); int mask = BIT(q);
...@@ -932,7 +989,7 @@ static int ravb_poll(struct napi_struct *napi, int budget) ...@@ -932,7 +989,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)
/* Re-enable RX/TX interrupts */ /* Re-enable RX/TX interrupts */
spin_lock_irqsave(&priv->lock, flags); 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, RIC0, mask, mask);
ravb_modify(ndev, TIC, mask, mask); ravb_modify(ndev, TIC, mask, mask);
} else { } else {
...@@ -956,6 +1013,7 @@ static int ravb_poll(struct napi_struct *napi, int budget) ...@@ -956,6 +1013,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)
static void ravb_adjust_link(struct net_device *ndev) static void ravb_adjust_link(struct net_device *ndev)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
struct phy_device *phydev = ndev->phydev; struct phy_device *phydev = ndev->phydev;
bool new_state = false; bool new_state = false;
unsigned long flags; unsigned long flags;
...@@ -970,7 +1028,7 @@ static void ravb_adjust_link(struct net_device *ndev) ...@@ -970,7 +1028,7 @@ static void ravb_adjust_link(struct net_device *ndev)
if (phydev->speed != priv->speed) { if (phydev->speed != priv->speed) {
new_state = true; new_state = true;
priv->speed = phydev->speed; priv->speed = phydev->speed;
ravb_set_rate(ndev); info->set_rate(ndev);
} }
if (!priv->link) { if (!priv->link) {
ravb_modify(ndev, ECMR, ECMR_TXF, 0); ravb_modify(ndev, ECMR, ECMR_TXF, 0);
...@@ -1202,6 +1260,7 @@ static int ravb_set_ringparam(struct net_device *ndev, ...@@ -1202,6 +1260,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
struct ethtool_ringparam *ring) struct ethtool_ringparam *ring)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
int error; int error;
if (ring->tx_pending > BE_TX_RING_MAX || if (ring->tx_pending > BE_TX_RING_MAX ||
...@@ -1215,7 +1274,7 @@ static int ravb_set_ringparam(struct net_device *ndev, ...@@ -1215,7 +1274,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
if (netif_running(ndev)) { if (netif_running(ndev)) {
netif_device_detach(ndev); netif_device_detach(ndev);
/* Stop PTP Clock driver */ /* Stop PTP Clock driver */
if (priv->chip_id == RCAR_GEN2) if (info->no_ptp_cfg_active)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
/* Wait for DMA stopping */ /* Wait for DMA stopping */
error = ravb_stop_dma(ndev); error = ravb_stop_dma(ndev);
...@@ -1247,7 +1306,7 @@ static int ravb_set_ringparam(struct net_device *ndev, ...@@ -1247,7 +1306,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
ravb_emac_init(ndev); ravb_emac_init(ndev);
/* Initialise PTP Clock driver */ /* Initialise PTP Clock driver */
if (priv->chip_id == RCAR_GEN2) if (info->no_ptp_cfg_active)
ravb_ptp_init(ndev, priv->pdev); ravb_ptp_init(ndev, priv->pdev);
netif_device_attach(ndev); netif_device_attach(ndev);
...@@ -1338,6 +1397,7 @@ static inline int ravb_hook_irq(unsigned int irq, irq_handler_t handler, ...@@ -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) static int ravb_open(struct net_device *ndev)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
struct platform_device *pdev = priv->pdev; struct platform_device *pdev = priv->pdev;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
int error; int error;
...@@ -1345,7 +1405,7 @@ static int ravb_open(struct net_device *ndev) ...@@ -1345,7 +1405,7 @@ static int ravb_open(struct net_device *ndev)
napi_enable(&priv->napi[RAVB_BE]); napi_enable(&priv->napi[RAVB_BE]);
napi_enable(&priv->napi[RAVB_NC]); 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, error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED,
ndev->name, ndev); ndev->name, ndev);
if (error) { if (error) {
...@@ -1386,7 +1446,7 @@ static int ravb_open(struct net_device *ndev) ...@@ -1386,7 +1446,7 @@ static int ravb_open(struct net_device *ndev)
ravb_emac_init(ndev); ravb_emac_init(ndev);
/* Initialise PTP Clock driver */ /* Initialise PTP Clock driver */
if (priv->chip_id == RCAR_GEN2) if (info->no_ptp_cfg_active)
ravb_ptp_init(ndev, priv->pdev); ravb_ptp_init(ndev, priv->pdev);
netif_tx_start_all_queues(ndev); netif_tx_start_all_queues(ndev);
...@@ -1400,10 +1460,10 @@ static int ravb_open(struct net_device *ndev) ...@@ -1400,10 +1460,10 @@ static int ravb_open(struct net_device *ndev)
out_ptp_stop: out_ptp_stop:
/* Stop PTP Clock driver */ /* Stop PTP Clock driver */
if (priv->chip_id == RCAR_GEN2) if (info->no_ptp_cfg_active)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
out_free_irq_nc_tx: out_free_irq_nc_tx:
if (priv->chip_id == RCAR_GEN2) if (!info->multi_irqs)
goto out_free_irq; goto out_free_irq;
free_irq(priv->tx_irqs[RAVB_NC], ndev); free_irq(priv->tx_irqs[RAVB_NC], ndev);
out_free_irq_nc_rx: out_free_irq_nc_rx:
...@@ -1441,13 +1501,14 @@ static void ravb_tx_timeout_work(struct work_struct *work) ...@@ -1441,13 +1501,14 @@ static void ravb_tx_timeout_work(struct work_struct *work)
{ {
struct ravb_private *priv = container_of(work, struct ravb_private, struct ravb_private *priv = container_of(work, struct ravb_private,
work); work);
const struct ravb_hw_info *info = priv->info;
struct net_device *ndev = priv->ndev; struct net_device *ndev = priv->ndev;
int error; int error;
netif_tx_stop_all_queues(ndev); netif_tx_stop_all_queues(ndev);
/* Stop PTP Clock driver */ /* Stop PTP Clock driver */
if (priv->chip_id == RCAR_GEN2) if (info->no_ptp_cfg_active)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
/* Wait for DMA stopping */ /* Wait for DMA stopping */
...@@ -1482,7 +1543,7 @@ static void ravb_tx_timeout_work(struct work_struct *work) ...@@ -1482,7 +1543,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
out: out:
/* Initialise PTP Clock driver */ /* Initialise PTP Clock driver */
if (priv->chip_id == RCAR_GEN2) if (info->no_ptp_cfg_active)
ravb_ptp_init(ndev, priv->pdev); ravb_ptp_init(ndev, priv->pdev);
netif_tx_start_all_queues(ndev); netif_tx_start_all_queues(ndev);
...@@ -1680,6 +1741,7 @@ static int ravb_close(struct net_device *ndev) ...@@ -1680,6 +1741,7 @@ static int ravb_close(struct net_device *ndev)
{ {
struct device_node *np = ndev->dev.parent->of_node; struct device_node *np = ndev->dev.parent->of_node;
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
struct ravb_tstamp_skb *ts_skb, *ts_skb2; struct ravb_tstamp_skb *ts_skb, *ts_skb2;
netif_tx_stop_all_queues(ndev); netif_tx_stop_all_queues(ndev);
...@@ -1690,7 +1752,7 @@ static int ravb_close(struct net_device *ndev) ...@@ -1690,7 +1752,7 @@ static int ravb_close(struct net_device *ndev)
ravb_write(ndev, 0, TIC); ravb_write(ndev, 0, TIC);
/* Stop PTP Clock driver */ /* Stop PTP Clock driver */
if (priv->chip_id == RCAR_GEN2) if (info->no_ptp_cfg_active)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
/* Set the config mode to stop the AVB-DMAC's processes */ /* Set the config mode to stop the AVB-DMAC's processes */
...@@ -1713,7 +1775,7 @@ static int ravb_close(struct net_device *ndev) ...@@ -1713,7 +1775,7 @@ static int ravb_close(struct net_device *ndev)
of_phy_deregister_fixed_link(np); 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->tx_irqs[RAVB_NC], ndev);
free_irq(priv->rx_irqs[RAVB_NC], ndev); free_irq(priv->rx_irqs[RAVB_NC], ndev);
free_irq(priv->tx_irqs[RAVB_BE], 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) ...@@ -1856,7 +1918,7 @@ static void ravb_set_rx_csum(struct net_device *ndev, bool enable)
spin_unlock_irqrestore(&priv->lock, flags); 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 features)
{ {
netdev_features_t changed = ndev->features ^ features; netdev_features_t changed = ndev->features ^ features;
...@@ -1869,6 +1931,15 @@ static int ravb_set_features(struct net_device *ndev, ...@@ -1869,6 +1931,15 @@ static int ravb_set_features(struct net_device *ndev,
return 0; 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 = { static const struct net_device_ops ravb_netdev_ops = {
.ndo_open = ravb_open, .ndo_open = ravb_open,
.ndo_stop = ravb_close, .ndo_stop = ravb_close,
...@@ -1930,26 +2001,43 @@ static int ravb_mdio_release(struct ravb_private *priv) ...@@ -1930,26 +2001,43 @@ static int ravb_mdio_release(struct ravb_private *priv)
} }
static const struct ravb_hw_info ravb_gen3_hw_info = { 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_stats = ravb_gstrings_stats,
.gstrings_size = sizeof(ravb_gstrings_stats), .gstrings_size = sizeof(ravb_gstrings_stats),
.net_hw_features = NETIF_F_RXCSUM, .net_hw_features = NETIF_F_RXCSUM,
.net_features = NETIF_F_RXCSUM, .net_features = NETIF_F_RXCSUM,
.chip_id = RCAR_GEN3,
.stats_len = ARRAY_SIZE(ravb_gstrings_stats), .stats_len = ARRAY_SIZE(ravb_gstrings_stats),
.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1, .max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
.internal_delay = 1, .internal_delay = 1,
.tx_counters = 1, .tx_counters = 1,
.multi_irqs = 1,
.ptp_cfg_active = 1,
}; };
static const struct ravb_hw_info ravb_gen2_hw_info = { 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_stats = ravb_gstrings_stats,
.gstrings_size = sizeof(ravb_gstrings_stats), .gstrings_size = sizeof(ravb_gstrings_stats),
.net_hw_features = NETIF_F_RXCSUM, .net_hw_features = NETIF_F_RXCSUM,
.net_features = NETIF_F_RXCSUM, .net_features = NETIF_F_RXCSUM,
.chip_id = RCAR_GEN2,
.stats_len = ARRAY_SIZE(ravb_gstrings_stats), .stats_len = ARRAY_SIZE(ravb_gstrings_stats),
.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1, .max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
.aligned_tx = 1, .aligned_tx = 1,
.no_ptp_cfg_active = 1,
}; };
static const struct of_device_id ravb_match_table[] = { static const struct of_device_id ravb_match_table[] = {
...@@ -1990,8 +2078,9 @@ static int ravb_set_gti(struct net_device *ndev) ...@@ -1990,8 +2078,9 @@ static int ravb_set_gti(struct net_device *ndev)
static void ravb_set_config_mode(struct net_device *ndev) static void ravb_set_config_mode(struct net_device *ndev)
{ {
struct ravb_private *priv = netdev_priv(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); ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG);
/* Set CSEL value */ /* Set CSEL value */
ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB); ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB);
...@@ -2052,6 +2141,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2052,6 +2141,7 @@ static int ravb_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
const struct ravb_hw_info *info; const struct ravb_hw_info *info;
struct reset_control *rstc;
struct ravb_private *priv; struct ravb_private *priv;
struct net_device *ndev; struct net_device *ndev;
int error, irq, q; int error, irq, q;
...@@ -2064,6 +2154,11 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2064,6 +2154,11 @@ static int ravb_probe(struct platform_device *pdev)
return -EINVAL; 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), ndev = alloc_etherdev_mqs(sizeof(struct ravb_private),
NUM_TX_QUEUE, NUM_RX_QUEUE); NUM_TX_QUEUE, NUM_RX_QUEUE);
if (!ndev) if (!ndev)
...@@ -2074,10 +2169,11 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2074,10 +2169,11 @@ static int ravb_probe(struct platform_device *pdev)
ndev->features = info->net_features; ndev->features = info->net_features;
ndev->hw_features = info->net_hw_features; ndev->hw_features = info->net_hw_features;
reset_control_deassert(rstc);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&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"); irq = platform_get_irq_byname(pdev, "ch22");
else else
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
...@@ -2091,6 +2187,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2091,6 +2187,7 @@ static int ravb_probe(struct platform_device *pdev)
priv = netdev_priv(ndev); priv = netdev_priv(ndev);
priv->info = info; priv->info = info;
priv->rstc = rstc;
priv->ndev = ndev; priv->ndev = ndev;
priv->pdev = pdev; priv->pdev = pdev;
priv->num_tx_ring[RAVB_BE] = BE_TX_RING_SIZE; priv->num_tx_ring[RAVB_BE] = BE_TX_RING_SIZE;
...@@ -2117,7 +2214,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2117,7 +2214,7 @@ static int ravb_probe(struct platform_device *pdev)
priv->avb_link_active_low = priv->avb_link_active_low =
of_property_read_bool(np, "renesas,ether-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"); irq = platform_get_irq_byname(pdev, "ch24");
if (irq < 0) { if (irq < 0) {
error = irq; error = irq;
...@@ -2142,8 +2239,6 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -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); priv->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(priv->clk)) { if (IS_ERR(priv->clk)) {
error = PTR_ERR(priv->clk); error = PTR_ERR(priv->clk);
...@@ -2160,8 +2255,12 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2160,8 +2255,12 @@ static int ravb_probe(struct platform_device *pdev)
ndev->max_mtu = 2048 - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN); ndev->max_mtu = 2048 - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
ndev->min_mtu = ETH_MIN_MTU; ndev->min_mtu = ETH_MIN_MTU;
priv->num_tx_desc = info->aligned_tx ? /* FIXME: R-Car Gen2 has 4byte alignment restriction for tx buffer
NUM_TX_DESC_GEN2 : NUM_TX_DESC_GEN3; * 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 */ /* Set function */
ndev->netdev_ops = &ravb_netdev_ops; ndev->netdev_ops = &ravb_netdev_ops;
...@@ -2202,7 +2301,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2202,7 +2301,7 @@ static int ravb_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&priv->ts_skb_list); INIT_LIST_HEAD(&priv->ts_skb_list);
/* Initialise PTP Clock driver */ /* Initialise PTP Clock driver */
if (info->chip_id != RCAR_GEN2) if (info->ptp_cfg_active)
ravb_ptp_init(ndev, pdev); ravb_ptp_init(ndev, pdev);
/* Debug message level */ /* Debug message level */
...@@ -2250,7 +2349,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2250,7 +2349,7 @@ static int ravb_probe(struct platform_device *pdev)
priv->desc_bat_dma); priv->desc_bat_dma);
/* Stop PTP Clock driver */ /* Stop PTP Clock driver */
if (info->chip_id != RCAR_GEN2) if (info->ptp_cfg_active)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
out_disable_refclk: out_disable_refclk:
clk_disable_unprepare(priv->refclk); clk_disable_unprepare(priv->refclk);
...@@ -2259,6 +2358,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2259,6 +2358,7 @@ static int ravb_probe(struct platform_device *pdev)
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
reset_control_assert(rstc);
return error; return error;
} }
...@@ -2266,9 +2366,10 @@ static int ravb_remove(struct platform_device *pdev) ...@@ -2266,9 +2366,10 @@ static int ravb_remove(struct platform_device *pdev)
{ {
struct net_device *ndev = platform_get_drvdata(pdev); struct net_device *ndev = platform_get_drvdata(pdev);
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
/* Stop PTP Clock driver */ /* Stop PTP Clock driver */
if (priv->chip_id != RCAR_GEN2) if (info->ptp_cfg_active)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
clk_disable_unprepare(priv->refclk); clk_disable_unprepare(priv->refclk);
...@@ -2283,6 +2384,7 @@ static int ravb_remove(struct platform_device *pdev) ...@@ -2283,6 +2384,7 @@ static int ravb_remove(struct platform_device *pdev)
netif_napi_del(&priv->napi[RAVB_BE]); netif_napi_del(&priv->napi[RAVB_BE]);
ravb_mdio_release(priv); ravb_mdio_release(priv);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
reset_control_assert(priv->rstc);
free_netdev(ndev); free_netdev(ndev);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
......
...@@ -179,6 +179,7 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp, ...@@ -179,6 +179,7 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
{ {
struct ravb_private *priv = container_of(ptp, struct ravb_private, struct ravb_private *priv = container_of(ptp, struct ravb_private,
ptp.info); ptp.info);
const struct ravb_hw_info *info = priv->info;
struct net_device *ndev = priv->ndev; struct net_device *ndev = priv->ndev;
unsigned long flags; unsigned long flags;
...@@ -197,7 +198,7 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp, ...@@ -197,7 +198,7 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
priv->ptp.extts[req->index] = on; priv->ptp.extts[req->index] = on;
spin_lock_irqsave(&priv->lock, flags); 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); ravb_modify(ndev, GIC, GIC_PTCE, on ? GIC_PTCE : 0);
else if (on) else if (on)
ravb_write(ndev, GIE_PTCS, GIE); ravb_write(ndev, GIE_PTCS, GIE);
...@@ -213,6 +214,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp, ...@@ -213,6 +214,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
{ {
struct ravb_private *priv = container_of(ptp, struct ravb_private, struct ravb_private *priv = container_of(ptp, struct ravb_private,
ptp.info); ptp.info);
const struct ravb_hw_info *info = priv->info;
struct net_device *ndev = priv->ndev; struct net_device *ndev = priv->ndev;
struct ravb_ptp_perout *perout; struct ravb_ptp_perout *perout;
unsigned long flags; unsigned long flags;
...@@ -252,7 +254,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp, ...@@ -252,7 +254,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
error = ravb_ptp_update_compare(priv, (u32)start_ns); error = ravb_ptp_update_compare(priv, (u32)start_ns);
if (!error) { if (!error) {
/* Unmask interrupt */ /* Unmask interrupt */
if (priv->chip_id == RCAR_GEN2) if (!info->multi_irqs)
ravb_modify(ndev, GIC, GIC_PTME, GIC_PTME); ravb_modify(ndev, GIC, GIC_PTME, GIC_PTME);
else else
ravb_write(ndev, GIE_PTMS0, GIE); ravb_write(ndev, GIE_PTMS0, GIE);
...@@ -264,7 +266,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp, ...@@ -264,7 +266,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
perout->period = 0; perout->period = 0;
/* Mask interrupt */ /* Mask interrupt */
if (priv->chip_id == RCAR_GEN2) if (!info->multi_irqs)
ravb_modify(ndev, GIC, GIC_PTME, 0); ravb_modify(ndev, GIC, GIC_PTME, 0);
else else
ravb_write(ndev, GID_PTMD0, GID); 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