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

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
...@@ -81,6 +81,7 @@ enum ravb_reg { ...@@ -81,6 +81,7 @@ enum ravb_reg {
RQC3 = 0x00A0, RQC3 = 0x00A0,
RQC4 = 0x00A4, RQC4 = 0x00A4,
RPC = 0x00B0, RPC = 0x00B0,
RTC = 0x00B4, /* R-Car Gen3 and RZ/G2L only */
UFCW = 0x00BC, UFCW = 0x00BC,
UFCS = 0x00C0, UFCS = 0x00C0,
UFCV0 = 0x00C4, UFCV0 = 0x00C4,
...@@ -187,13 +188,14 @@ enum ravb_reg { ...@@ -187,13 +188,14 @@ enum ravb_reg {
PIR = 0x0520, PIR = 0x0520,
PSR = 0x0528, PSR = 0x0528,
PIPR = 0x052c, PIPR = 0x052c,
CXR31 = 0x0530, /* RZ/G2L only */
MPR = 0x0558, MPR = 0x0558,
PFTCR = 0x055c, PFTCR = 0x055c,
PFRCR = 0x0560, PFRCR = 0x0560,
GECMR = 0x05b0, GECMR = 0x05b0,
MAHR = 0x05c0, MAHR = 0x05c0,
MALR = 0x05c8, MALR = 0x05c8,
TROCR = 0x0700, /* R-Car Gen3 only */ TROCR = 0x0700, /* R-Car Gen3 and RZ/G2L only */
CEFCR = 0x0740, CEFCR = 0x0740,
FRECR = 0x0748, FRECR = 0x0748,
TSFRCR = 0x0750, TSFRCR = 0x0750,
...@@ -810,10 +812,11 @@ enum ECMR_BIT { ...@@ -810,10 +812,11 @@ enum ECMR_BIT {
ECMR_TXF = 0x00010000, /* Documented for R-Car Gen3 only */ ECMR_TXF = 0x00010000, /* Documented for R-Car Gen3 only */
ECMR_RXF = 0x00020000, ECMR_RXF = 0x00020000,
ECMR_PFR = 0x00040000, 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_RZPF = 0x00100000,
ECMR_DPAD = 0x00200000, ECMR_DPAD = 0x00200000,
ECMR_RCSC = 0x00800000, ECMR_RCSC = 0x00800000,
ECMR_RCPT = 0x02000000, /* Documented for RZ/G2L only */
ECMR_TRCCM = 0x04000000, ECMR_TRCCM = 0x04000000,
}; };
...@@ -823,6 +826,7 @@ enum ECSR_BIT { ...@@ -823,6 +826,7 @@ enum ECSR_BIT {
ECSR_MPD = 0x00000002, ECSR_MPD = 0x00000002,
ECSR_LCHNG = 0x00000004, ECSR_LCHNG = 0x00000004,
ECSR_PHYI = 0x00000008, ECSR_PHYI = 0x00000008,
ECSR_PFRI = 0x00000010,
}; };
/* ECSIPR */ /* ECSIPR */
...@@ -857,9 +861,13 @@ enum MPR_BIT { ...@@ -857,9 +861,13 @@ enum MPR_BIT {
/* GECMR */ /* GECMR */
enum GECMR_BIT { enum GECMR_BIT {
GECMR_SPEED = 0x00000001, GECMR_SPEED = 0x00000001,
GECMR_SPEED_100 = 0x00000000, GECMR_SPEED_100 = 0x00000000,
GECMR_SPEED_1000 = 0x00000001, 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. */ /* The Ethernet AVB descriptor definitions. */
...@@ -949,6 +957,11 @@ enum RAVB_QUEUE { ...@@ -949,6 +957,11 @@ enum RAVB_QUEUE {
RAVB_NC, /* Network Control Queue */ RAVB_NC, /* Network Control Queue */
}; };
enum CXR31_BIT {
CXR31_SEL_LINK0 = 0x00000001,
CXR31_SEL_LINK1 = 0x00000008,
};
#define DBAT_ENTRY_NUM 22 #define DBAT_ENTRY_NUM 22
#define RX_QUEUE_OFFSET 4 #define RX_QUEUE_OFFSET 4
#define NUM_RX_QUEUE 2 #define NUM_RX_QUEUE 2
...@@ -956,6 +969,8 @@ enum RAVB_QUEUE { ...@@ -956,6 +969,8 @@ enum RAVB_QUEUE {
#define RX_BUF_SZ (2048 - ETH_FCS_LEN + sizeof(__sum16)) #define RX_BUF_SZ (2048 - ETH_FCS_LEN + sizeof(__sum16))
#define GBETH_RX_BUFF_MAX 8192
struct ravb_tstamp_skb { struct ravb_tstamp_skb {
struct list_head list; struct list_head list;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -985,8 +1000,8 @@ struct ravb_hw_info { ...@@ -985,8 +1000,8 @@ struct ravb_hw_info {
void *(*alloc_rx_desc)(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); bool (*receive)(struct net_device *ndev, int *quota, int q);
void (*set_rate)(struct net_device *ndev); void (*set_rate)(struct net_device *ndev);
int (*set_rx_csum_feature)(struct net_device *ndev, netdev_features_t features); int (*set_feature)(struct net_device *ndev, netdev_features_t features);
void (*dmac_init)(struct net_device *ndev); int (*dmac_init)(struct net_device *ndev);
void (*emac_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;
...@@ -994,14 +1009,18 @@ struct ravb_hw_info { ...@@ -994,14 +1009,18 @@ struct ravb_hw_info {
netdev_features_t net_features; netdev_features_t net_features;
int stats_len; int stats_len;
size_t max_rx_len; size_t max_rx_len;
u32 tsrq;
unsigned aligned_tx: 1; unsigned aligned_tx: 1;
/* 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 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 gptp:1; /* AVB-DMAC has gPTP support */
unsigned ptp_cfg_active:1; /* AVB-DMAC has gPTP support active in config mode */ 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 { struct ravb_private {
...@@ -1056,6 +1075,8 @@ struct ravb_private { ...@@ -1056,6 +1075,8 @@ struct ravb_private {
unsigned rgmii_override:1; /* Deprecated rgmii-*id behavior */ unsigned rgmii_override:1; /* Deprecated rgmii-*id behavior */
unsigned int num_tx_desc; /* TX descriptors per packet */ unsigned int num_tx_desc; /* TX descriptors per packet */
int duplex;
const struct ravb_hw_info *info; const struct ravb_hw_info *info;
struct reset_control *rstc; struct reset_control *rstc;
}; };
......
...@@ -83,7 +83,24 @@ static int ravb_config(struct net_device *ndev) ...@@ -83,7 +83,24 @@ static int ravb_config(struct net_device *ndev)
return error; 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); 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) ...@@ -217,6 +234,11 @@ static int ravb_tx_free(struct net_device *ndev, int q, bool free_txed_only)
return free_num; 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) static void ravb_rx_ring_free(struct net_device *ndev, int q)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
...@@ -283,6 +305,11 @@ static void ravb_ring_free(struct net_device *ndev, int q) ...@@ -283,6 +305,11 @@ static void ravb_ring_free(struct net_device *ndev, int q)
priv->tx_skb[q] = NULL; 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) static void ravb_rx_ring_format(struct net_device *ndev, int q)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
...@@ -356,6 +383,12 @@ static void ravb_ring_format(struct net_device *ndev, int q) ...@@ -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]); 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) static void *ravb_alloc_rx_desc(struct net_device *ndev, int q)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
...@@ -426,7 +459,37 @@ static int ravb_ring_init(struct net_device *ndev, int q) ...@@ -426,7 +459,37 @@ static int ravb_ring_init(struct net_device *ndev, int q)
return -ENOMEM; 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 */ /* 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);
...@@ -436,7 +499,7 @@ static void ravb_rcar_emac_init(struct net_device *ndev) ...@@ -436,7 +499,7 @@ static void ravb_rcar_emac_init(struct net_device *ndev)
(ndev->features & NETIF_F_RXCSUM ? ECMR_RCSC : 0) | (ndev->features & NETIF_F_RXCSUM ? ECMR_RCSC : 0) |
ECMR_TE | ECMR_RE, ECMR); ECMR_TE | ECMR_RE, ECMR);
ravb_set_rate(ndev); ravb_set_rate_rcar(ndev);
/* Set MAC address */ /* Set MAC address */
ravb_write(ndev, ravb_write(ndev,
...@@ -461,10 +524,58 @@ static void ravb_emac_init(struct net_device *ndev) ...@@ -461,10 +524,58 @@ static void ravb_emac_init(struct net_device *ndev)
info->emac_init(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); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info; 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 */ /* Set AVB RX */
ravb_write(ndev, ravb_write(ndev,
...@@ -491,6 +602,8 @@ static void ravb_rcar_dmac_init(struct net_device *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); 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);
return 0;
} }
/* Device init function for Ethernet AVB */ /* Device init function for Ethernet AVB */
...@@ -505,20 +618,9 @@ static int ravb_dmac_init(struct net_device *ndev) ...@@ -505,20 +618,9 @@ static int ravb_dmac_init(struct net_device *ndev)
if (error) if (error)
return error; return error;
error = ravb_ring_init(ndev, RAVB_BE); error = info->dmac_init(ndev);
if (error) if (error)
return 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);
...@@ -579,6 +681,14 @@ static void ravb_rx_csum(struct sk_buff *skb) ...@@ -579,6 +681,14 @@ 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 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) static bool ravb_rcar_rx(struct net_device *ndev, int *quota, int q)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
...@@ -717,11 +827,13 @@ static void ravb_rcv_snd_enable(struct net_device *ndev) ...@@ -717,11 +827,13 @@ static void ravb_rcv_snd_enable(struct net_device *ndev)
/* function for waiting dma process finished */ /* function for waiting dma process finished */
static int ravb_stop_dma(struct net_device *ndev) 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; int error;
/* Wait for stopping the hardware TX process */ /* Wait for stopping the hardware TX process */
error = ravb_wait(ndev, TCCR, error = ravb_wait(ndev, TCCR, info->tsrq, 0);
TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3, 0);
if (error) if (error)
return error; return error;
...@@ -859,6 +971,7 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id) ...@@ -859,6 +971,7 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
{ {
struct net_device *ndev = dev_id; struct net_device *ndev = dev_id;
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
irqreturn_t result = IRQ_NONE; irqreturn_t result = IRQ_NONE;
u32 iss; u32 iss;
...@@ -875,8 +988,13 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id) ...@@ -875,8 +988,13 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
result = IRQ_HANDLED; result = IRQ_HANDLED;
/* Network control and best effort queue RX/TX */ /* Network control and best effort queue RX/TX */
for (q = RAVB_NC; q >= RAVB_BE; q--) { if (info->nc_queue) {
if (ravb_queue_interrupt(ndev, q)) 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; result = IRQ_HANDLED;
} }
} }
...@@ -1000,7 +1118,8 @@ static int ravb_poll(struct napi_struct *napi, int budget) ...@@ -1000,7 +1118,8 @@ static int ravb_poll(struct napi_struct *napi, int budget)
/* Receive error message handling */ /* Receive error message handling */
priv->rx_over_errors = priv->stats[RAVB_BE].rx_over_errors; priv->rx_over_errors = priv->stats[RAVB_BE].rx_over_errors;
priv->rx_over_errors += priv->stats[RAVB_NC].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) if (priv->rx_over_errors != ndev->stats.rx_over_errors)
ndev->stats.rx_over_errors = priv->rx_over_errors; ndev->stats.rx_over_errors = priv->rx_over_errors;
if (priv->rx_fifo_errors != ndev->stats.rx_fifo_errors) if (priv->rx_fifo_errors != ndev->stats.rx_fifo_errors)
...@@ -1009,6 +1128,13 @@ static int ravb_poll(struct napi_struct *napi, int budget) ...@@ -1009,6 +1128,13 @@ static int ravb_poll(struct napi_struct *napi, int budget)
return budget - quota; 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 */ /* PHY state control function */
static void ravb_adjust_link(struct net_device *ndev) static void ravb_adjust_link(struct net_device *ndev)
{ {
...@@ -1025,6 +1151,12 @@ 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); ravb_rcv_snd_disable(ndev);
if (phydev->link) { 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) { if (phydev->speed != priv->speed) {
new_state = true; new_state = true;
priv->speed = phydev->speed; priv->speed = phydev->speed;
...@@ -1039,6 +1171,8 @@ static void ravb_adjust_link(struct net_device *ndev) ...@@ -1039,6 +1171,8 @@ static void ravb_adjust_link(struct net_device *ndev)
new_state = true; new_state = true;
priv->link = 0; priv->link = 0;
priv->speed = 0; priv->speed = 0;
if (info->half_duplex)
priv->duplex = -1;
} }
/* Enable TX and RX right over here, if E-MAC change is ignored */ /* 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) ...@@ -1061,6 +1195,7 @@ static int ravb_phy_init(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 phy_device *phydev; struct phy_device *phydev;
struct device_node *pn; struct device_node *pn;
phy_interface_t iface; phy_interface_t iface;
...@@ -1068,6 +1203,7 @@ static int ravb_phy_init(struct net_device *ndev) ...@@ -1068,6 +1203,7 @@ static int ravb_phy_init(struct net_device *ndev)
priv->link = 0; priv->link = 0;
priv->speed = 0; priv->speed = 0;
priv->duplex = -1;
/* Try connecting to PHY */ /* Try connecting to PHY */
pn = of_parse_phandle(np, "phy-handle", 0); pn = of_parse_phandle(np, "phy-handle", 0);
...@@ -1106,15 +1242,17 @@ static int ravb_phy_init(struct net_device *ndev) ...@@ -1106,15 +1242,17 @@ static int ravb_phy_init(struct net_device *ndev)
netdev_info(ndev, "limited PHY to 100Mbit/s\n"); netdev_info(ndev, "limited PHY to 100Mbit/s\n");
} }
/* 10BASE, Pause and Asym Pause is not supported */ if (!info->half_duplex) {
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); /* 10BASE, Pause and Asym Pause is not supported */
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT); phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Pause_BIT); phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Pause_BIT);
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT);
/* Half Duplex is not supported */ /* Half Duplex is not supported */
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
}
phy_attached_info(phydev); phy_attached_info(phydev);
...@@ -1208,11 +1346,14 @@ static void ravb_get_ethtool_stats(struct net_device *ndev, ...@@ -1208,11 +1346,14 @@ static void ravb_get_ethtool_stats(struct net_device *ndev,
struct ethtool_stats *estats, u64 *data) struct ethtool_stats *estats, u64 *data)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
int num_rx_q;
int i = 0; int i = 0;
int q; int q;
num_rx_q = info->nc_queue ? NUM_RX_QUEUE : 1;
/* Device-specific stats */ /* 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]; struct net_device_stats *stats = &priv->stats[q];
data[i++] = priv->cur_rx[q]; data[i++] = priv->cur_rx[q];
...@@ -1274,7 +1415,7 @@ static int ravb_set_ringparam(struct net_device *ndev, ...@@ -1274,7 +1415,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 (info->no_ptp_cfg_active) if (info->gptp)
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);
...@@ -1287,7 +1428,8 @@ static int ravb_set_ringparam(struct net_device *ndev, ...@@ -1287,7 +1428,8 @@ static int ravb_set_ringparam(struct net_device *ndev,
/* Free all the skb's in the RX queue and the DMA buffers. */ /* Free all the skb's in the RX queue and the DMA buffers. */
ravb_ring_free(ndev, RAVB_BE); ravb_ring_free(ndev, RAVB_BE);
ravb_ring_free(ndev, RAVB_NC); if (info->nc_queue)
ravb_ring_free(ndev, RAVB_NC);
} }
/* Set new parameters */ /* Set new parameters */
...@@ -1306,7 +1448,7 @@ static int ravb_set_ringparam(struct net_device *ndev, ...@@ -1306,7 +1448,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 (info->no_ptp_cfg_active) if (info->gptp)
ravb_ptp_init(ndev, priv->pdev); ravb_ptp_init(ndev, priv->pdev);
netif_device_attach(ndev); netif_device_attach(ndev);
...@@ -1319,6 +1461,7 @@ static int ravb_get_ts_info(struct net_device *ndev, ...@@ -1319,6 +1461,7 @@ static int ravb_get_ts_info(struct net_device *ndev,
struct ethtool_ts_info *info) struct ethtool_ts_info *info)
{ {
struct ravb_private *priv = netdev_priv(ndev); struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *hw_info = priv->info;
info->so_timestamping = info->so_timestamping =
SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_TX_SOFTWARE |
...@@ -1332,7 +1475,8 @@ static int ravb_get_ts_info(struct net_device *ndev, ...@@ -1332,7 +1475,8 @@ static int ravb_get_ts_info(struct net_device *ndev,
(1 << HWTSTAMP_FILTER_NONE) | (1 << HWTSTAMP_FILTER_NONE) |
(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
(1 << HWTSTAMP_FILTER_ALL); (1 << HWTSTAMP_FILTER_ALL);
info->phc_index = ptp_clock_index(priv->ptp.clock); if (hw_info->gptp || hw_info->ccc_gac)
info->phc_index = ptp_clock_index(priv->ptp.clock);
return 0; return 0;
} }
...@@ -1348,8 +1492,9 @@ static void ravb_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) ...@@ -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) static int ravb_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
{ {
struct ravb_private *priv = netdev_priv(ndev); 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; return -EOPNOTSUPP;
priv->wol_enabled = !!(wol->wolopts & WAKE_MAGIC); priv->wol_enabled = !!(wol->wolopts & WAKE_MAGIC);
...@@ -1403,7 +1548,8 @@ static int ravb_open(struct net_device *ndev) ...@@ -1403,7 +1548,8 @@ static int ravb_open(struct net_device *ndev)
int error; int error;
napi_enable(&priv->napi[RAVB_BE]); napi_enable(&priv->napi[RAVB_BE]);
napi_enable(&priv->napi[RAVB_NC]); if (info->nc_queue)
napi_enable(&priv->napi[RAVB_NC]);
if (!info->multi_irqs) { if (!info->multi_irqs) {
error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED, error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED,
...@@ -1446,7 +1592,7 @@ static int ravb_open(struct net_device *ndev) ...@@ -1446,7 +1592,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 (info->no_ptp_cfg_active) if (info->gptp)
ravb_ptp_init(ndev, priv->pdev); ravb_ptp_init(ndev, priv->pdev);
netif_tx_start_all_queues(ndev); netif_tx_start_all_queues(ndev);
...@@ -1460,7 +1606,7 @@ static int ravb_open(struct net_device *ndev) ...@@ -1460,7 +1606,7 @@ static int ravb_open(struct net_device *ndev)
out_ptp_stop: out_ptp_stop:
/* Stop PTP Clock driver */ /* Stop PTP Clock driver */
if (info->no_ptp_cfg_active) if (info->gptp)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
out_free_irq_nc_tx: out_free_irq_nc_tx:
if (!info->multi_irqs) if (!info->multi_irqs)
...@@ -1477,7 +1623,8 @@ static int ravb_open(struct net_device *ndev) ...@@ -1477,7 +1623,8 @@ static int ravb_open(struct net_device *ndev)
out_free_irq: out_free_irq:
free_irq(ndev->irq, ndev); free_irq(ndev->irq, ndev);
out_napi_off: out_napi_off:
napi_disable(&priv->napi[RAVB_NC]); if (info->nc_queue)
napi_disable(&priv->napi[RAVB_NC]);
napi_disable(&priv->napi[RAVB_BE]); napi_disable(&priv->napi[RAVB_BE]);
return error; return error;
} }
...@@ -1508,7 +1655,7 @@ static void ravb_tx_timeout_work(struct work_struct *work) ...@@ -1508,7 +1655,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
netif_tx_stop_all_queues(ndev); netif_tx_stop_all_queues(ndev);
/* Stop PTP Clock driver */ /* Stop PTP Clock driver */
if (info->no_ptp_cfg_active) if (info->gptp)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
/* Wait for DMA stopping */ /* Wait for DMA stopping */
...@@ -1526,7 +1673,8 @@ static void ravb_tx_timeout_work(struct work_struct *work) ...@@ -1526,7 +1673,8 @@ static void ravb_tx_timeout_work(struct work_struct *work)
} }
ravb_ring_free(ndev, RAVB_BE); ravb_ring_free(ndev, RAVB_BE);
ravb_ring_free(ndev, RAVB_NC); if (info->nc_queue)
ravb_ring_free(ndev, RAVB_NC);
/* Device init */ /* Device init */
error = ravb_dmac_init(ndev); error = ravb_dmac_init(ndev);
...@@ -1543,7 +1691,7 @@ static void ravb_tx_timeout_work(struct work_struct *work) ...@@ -1543,7 +1691,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
out: out:
/* Initialise PTP Clock driver */ /* Initialise PTP Clock driver */
if (info->no_ptp_cfg_active) if (info->gptp)
ravb_ptp_init(ndev, priv->pdev); ravb_ptp_init(ndev, priv->pdev);
netif_tx_start_all_queues(ndev); netif_tx_start_all_queues(ndev);
...@@ -1553,6 +1701,7 @@ static void ravb_tx_timeout_work(struct work_struct *work) ...@@ -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) static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, 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;
unsigned int num_tx_desc = priv->num_tx_desc; unsigned int num_tx_desc = priv->num_tx_desc;
u16 q = skb_get_queue_mapping(skb); u16 q = skb_get_queue_mapping(skb);
struct ravb_tstamp_skb *ts_skb; struct ravb_tstamp_skb *ts_skb;
...@@ -1629,28 +1778,30 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -1629,28 +1778,30 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
desc->dptr = cpu_to_le32(dma_addr); desc->dptr = cpu_to_le32(dma_addr);
/* TX timestamp required */ /* TX timestamp required */
if (q == RAVB_NC) { if (info->gptp || info->ccc_gac) {
ts_skb = kmalloc(sizeof(*ts_skb), GFP_ATOMIC); if (q == RAVB_NC) {
if (!ts_skb) { ts_skb = kmalloc(sizeof(*ts_skb), GFP_ATOMIC);
if (num_tx_desc > 1) { if (!ts_skb) {
desc--; if (num_tx_desc > 1) {
dma_unmap_single(ndev->dev.parent, dma_addr, desc--;
len, DMA_TO_DEVICE); dma_unmap_single(ndev->dev.parent, dma_addr,
len, DMA_TO_DEVICE);
}
goto unmap;
} }
goto unmap; ts_skb->skb = skb_get(skb);
ts_skb->tag = priv->ts_skb_tag++;
priv->ts_skb_tag &= 0x3ff;
list_add_tail(&ts_skb->list, &priv->ts_skb_list);
/* TAG and timestamp required flag */
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
desc->tagh_tsr = (ts_skb->tag >> 4) | TX_TSR;
desc->ds_tagl |= cpu_to_le16(ts_skb->tag << 12);
} }
ts_skb->skb = skb_get(skb);
ts_skb->tag = priv->ts_skb_tag++;
priv->ts_skb_tag &= 0x3ff;
list_add_tail(&ts_skb->list, &priv->ts_skb_list);
/* TAG and timestamp required flag */ skb_tx_timestamp(skb);
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
desc->tagh_tsr = (ts_skb->tag >> 4) | TX_TSR;
desc->ds_tagl |= cpu_to_le16(ts_skb->tag << 12);
} }
skb_tx_timestamp(skb);
/* Descriptor type must be set after all the above writes */ /* Descriptor type must be set after all the above writes */
dma_wmb(); dma_wmb();
if (num_tx_desc > 1) { if (num_tx_desc > 1) {
...@@ -1698,28 +1849,38 @@ static struct net_device_stats *ravb_get_stats(struct net_device *ndev) ...@@ -1698,28 +1849,38 @@ static struct net_device_stats *ravb_get_stats(struct net_device *ndev)
nstats = &ndev->stats; nstats = &ndev->stats;
stats0 = &priv->stats[RAVB_BE]; stats0 = &priv->stats[RAVB_BE];
stats1 = &priv->stats[RAVB_NC];
if (info->tx_counters) { if (info->tx_counters) {
nstats->tx_dropped += ravb_read(ndev, TROCR); nstats->tx_dropped += ravb_read(ndev, TROCR);
ravb_write(ndev, 0, TROCR); /* (write clear) */ ravb_write(ndev, 0, TROCR); /* (write clear) */
} }
nstats->rx_packets = stats0->rx_packets + stats1->rx_packets; nstats->rx_packets = stats0->rx_packets;
nstats->tx_packets = stats0->tx_packets + stats1->tx_packets; nstats->tx_packets = stats0->tx_packets;
nstats->rx_bytes = stats0->rx_bytes + stats1->rx_bytes; nstats->rx_bytes = stats0->rx_bytes;
nstats->tx_bytes = stats0->tx_bytes + stats1->tx_bytes; nstats->tx_bytes = stats0->tx_bytes;
nstats->multicast = stats0->multicast + stats1->multicast; nstats->multicast = stats0->multicast;
nstats->rx_errors = stats0->rx_errors + stats1->rx_errors; nstats->rx_errors = stats0->rx_errors;
nstats->rx_crc_errors = stats0->rx_crc_errors + stats1->rx_crc_errors; nstats->rx_crc_errors = stats0->rx_crc_errors;
nstats->rx_frame_errors = nstats->rx_frame_errors = stats0->rx_frame_errors;
stats0->rx_frame_errors + stats1->rx_frame_errors; nstats->rx_length_errors = stats0->rx_length_errors;
nstats->rx_length_errors = nstats->rx_missed_errors = stats0->rx_missed_errors;
stats0->rx_length_errors + stats1->rx_length_errors; nstats->rx_over_errors = stats0->rx_over_errors;
nstats->rx_missed_errors = if (info->nc_queue) {
stats0->rx_missed_errors + stats1->rx_missed_errors; stats1 = &priv->stats[RAVB_NC];
nstats->rx_over_errors =
stats0->rx_over_errors + stats1->rx_over_errors; 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; return nstats;
} }
...@@ -1752,7 +1913,7 @@ static int ravb_close(struct net_device *ndev) ...@@ -1752,7 +1913,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 (info->no_ptp_cfg_active) if (info->gptp)
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 */
...@@ -1761,10 +1922,12 @@ static int ravb_close(struct net_device *ndev) ...@@ -1761,10 +1922,12 @@ static int ravb_close(struct net_device *ndev)
"device will be stopped after h/w processes are done.\n"); "device will be stopped after h/w processes are done.\n");
/* Clear the timestamp list */ /* Clear the timestamp list */
list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) { if (info->gptp || info->ccc_gac) {
list_del(&ts_skb->list); list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) {
kfree_skb(ts_skb->skb); list_del(&ts_skb->list);
kfree(ts_skb); kfree_skb(ts_skb->skb);
kfree(ts_skb);
}
} }
/* PHY disconnect */ /* PHY disconnect */
...@@ -1784,12 +1947,14 @@ static int ravb_close(struct net_device *ndev) ...@@ -1784,12 +1947,14 @@ static int ravb_close(struct net_device *ndev)
} }
free_irq(ndev->irq, ndev); free_irq(ndev->irq, ndev);
napi_disable(&priv->napi[RAVB_NC]); if (info->nc_queue)
napi_disable(&priv->napi[RAVB_NC]);
napi_disable(&priv->napi[RAVB_BE]); napi_disable(&priv->napi[RAVB_BE]);
/* Free all the skb's in the RX queue and the DMA buffers. */ /* Free all the skb's in the RX queue and the DMA buffers. */
ravb_ring_free(ndev, RAVB_BE); ravb_ring_free(ndev, RAVB_BE);
ravb_ring_free(ndev, RAVB_NC); if (info->nc_queue)
ravb_ring_free(ndev, RAVB_NC);
return 0; return 0;
} }
...@@ -1918,8 +2083,15 @@ static void ravb_set_rx_csum(struct net_device *ndev, bool enable) ...@@ -1918,8 +2083,15 @@ 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_rx_csum(struct net_device *ndev, static int ravb_set_features_gbeth(struct net_device *ndev,
netdev_features_t features) 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; netdev_features_t changed = ndev->features ^ features;
...@@ -1937,7 +2109,7 @@ static int ravb_set_features(struct net_device *ndev, ...@@ -1937,7 +2109,7 @@ static int ravb_set_features(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; 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 = { static const struct net_device_ops ravb_netdev_ops = {
...@@ -2005,20 +2177,23 @@ static const struct ravb_hw_info ravb_gen3_hw_info = { ...@@ -2005,20 +2177,23 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
.rx_ring_format = ravb_rx_ring_format, .rx_ring_format = ravb_rx_ring_format,
.alloc_rx_desc = ravb_alloc_rx_desc, .alloc_rx_desc = ravb_alloc_rx_desc,
.receive = ravb_rcar_rx, .receive = ravb_rcar_rx,
.set_rate = ravb_set_rate, .set_rate = ravb_set_rate_rcar,
.set_rx_csum_feature = ravb_set_features_rx_csum, .set_feature = ravb_set_features_rcar,
.dmac_init = ravb_rcar_dmac_init, .dmac_init = ravb_dmac_init_rcar,
.emac_init = ravb_rcar_emac_init, .emac_init = ravb_emac_init_rcar,
.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,
.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,
.tsrq = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
.internal_delay = 1, .internal_delay = 1,
.tx_counters = 1, .tx_counters = 1,
.multi_irqs = 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 = { static const struct ravb_hw_info ravb_gen2_hw_info = {
...@@ -2026,18 +2201,37 @@ 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, .rx_ring_format = ravb_rx_ring_format,
.alloc_rx_desc = ravb_alloc_rx_desc, .alloc_rx_desc = ravb_alloc_rx_desc,
.receive = ravb_rcar_rx, .receive = ravb_rcar_rx,
.set_rate = ravb_set_rate, .set_rate = ravb_set_rate_rcar,
.set_rx_csum_feature = ravb_set_features_rx_csum, .set_feature = ravb_set_features_rcar,
.dmac_init = ravb_rcar_dmac_init, .dmac_init = ravb_dmac_init_rcar,
.emac_init = ravb_rcar_emac_init, .emac_init = ravb_emac_init_rcar,
.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,
.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,
.tsrq = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
.aligned_tx = 1, .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[] = { static const struct of_device_id ravb_match_table[] = {
...@@ -2046,6 +2240,7 @@ 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-rcar-gen2", .data = &ravb_gen2_hw_info },
{ .compatible = "renesas,etheravb-r8a7795", .data = &ravb_gen3_hw_info }, { .compatible = "renesas,etheravb-r8a7795", .data = &ravb_gen3_hw_info },
{ .compatible = "renesas,etheravb-rcar-gen3", .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); MODULE_DEVICE_TABLE(of, ravb_match_table);
...@@ -2080,13 +2275,15 @@ static void ravb_set_config_mode(struct net_device *ndev) ...@@ -2080,13 +2275,15 @@ 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; 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); 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);
} else { } else if (info->ccc_gac) {
ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG | ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG |
CCC_GAC | CCC_CSEL_HPB); 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) ...@@ -2192,8 +2389,11 @@ static int ravb_probe(struct platform_device *pdev)
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;
priv->num_rx_ring[RAVB_BE] = BE_RX_RING_SIZE; priv->num_rx_ring[RAVB_BE] = BE_RX_RING_SIZE;
priv->num_tx_ring[RAVB_NC] = NC_TX_RING_SIZE; if (info->nc_queue) {
priv->num_rx_ring[RAVB_NC] = NC_RX_RING_SIZE; 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); priv->addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(priv->addr)) { if (IS_ERR(priv->addr)) {
error = PTR_ERR(priv->addr); error = PTR_ERR(priv->addr);
...@@ -2269,13 +2469,15 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2269,13 +2469,15 @@ static int ravb_probe(struct platform_device *pdev)
/* Set AVB config mode */ /* Set AVB config mode */
ravb_set_config_mode(ndev); ravb_set_config_mode(ndev);
/* Set GTI value */ if (info->gptp || info->ccc_gac) {
error = ravb_set_gti(ndev); /* Set GTI value */
if (error) error = ravb_set_gti(ndev);
goto out_disable_refclk; if (error)
goto out_disable_refclk;
/* Request GTI loading */ /* Request GTI loading */
ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI); ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
}
if (info->internal_delay) { if (info->internal_delay) {
ravb_parse_delay_mode(np, ndev); ravb_parse_delay_mode(np, ndev);
...@@ -2301,7 +2503,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2301,7 +2503,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->ptp_cfg_active) if (info->ccc_gac)
ravb_ptp_init(ndev, pdev); ravb_ptp_init(ndev, pdev);
/* Debug message level */ /* Debug message level */
...@@ -2323,7 +2525,8 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2323,7 +2525,8 @@ static int ravb_probe(struct platform_device *pdev)
} }
netif_napi_add(ndev, &priv->napi[RAVB_BE], ravb_poll, 64); netif_napi_add(ndev, &priv->napi[RAVB_BE], ravb_poll, 64);
netif_napi_add(ndev, &priv->napi[RAVB_NC], ravb_poll, 64); if (info->nc_queue)
netif_napi_add(ndev, &priv->napi[RAVB_NC], ravb_poll, 64);
/* Network device register */ /* Network device register */
error = register_netdev(ndev); error = register_netdev(ndev);
...@@ -2341,7 +2544,9 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2341,7 +2544,9 @@ static int ravb_probe(struct platform_device *pdev)
return 0; return 0;
out_napi_del: out_napi_del:
netif_napi_del(&priv->napi[RAVB_NC]); if (info->nc_queue)
netif_napi_del(&priv->napi[RAVB_NC]);
netif_napi_del(&priv->napi[RAVB_BE]); netif_napi_del(&priv->napi[RAVB_BE]);
ravb_mdio_release(priv); ravb_mdio_release(priv);
out_dma_free: out_dma_free:
...@@ -2349,7 +2554,7 @@ static int ravb_probe(struct platform_device *pdev) ...@@ -2349,7 +2554,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->ptp_cfg_active) if (info->ccc_gac)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
out_disable_refclk: out_disable_refclk:
clk_disable_unprepare(priv->refclk); clk_disable_unprepare(priv->refclk);
...@@ -2369,7 +2574,7 @@ static int ravb_remove(struct platform_device *pdev) ...@@ -2369,7 +2574,7 @@ static int ravb_remove(struct platform_device *pdev)
const struct ravb_hw_info *info = priv->info; const struct ravb_hw_info *info = priv->info;
/* Stop PTP Clock driver */ /* Stop PTP Clock driver */
if (info->ptp_cfg_active) if (info->ccc_gac)
ravb_ptp_stop(ndev); ravb_ptp_stop(ndev);
clk_disable_unprepare(priv->refclk); clk_disable_unprepare(priv->refclk);
...@@ -2380,7 +2585,8 @@ static int ravb_remove(struct platform_device *pdev) ...@@ -2380,7 +2585,8 @@ static int ravb_remove(struct platform_device *pdev)
ravb_write(ndev, CCC_OPC_RESET, CCC); ravb_write(ndev, CCC_OPC_RESET, CCC);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
unregister_netdev(ndev); unregister_netdev(ndev);
netif_napi_del(&priv->napi[RAVB_NC]); if (info->nc_queue)
netif_napi_del(&priv->napi[RAVB_NC]);
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);
...@@ -2394,6 +2600,7 @@ static int ravb_remove(struct platform_device *pdev) ...@@ -2394,6 +2600,7 @@ static int ravb_remove(struct platform_device *pdev)
static int ravb_wol_setup(struct net_device *ndev) static int ravb_wol_setup(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;
/* Disable interrupts by clearing the interrupt masks. */ /* Disable interrupts by clearing the interrupt masks. */
ravb_write(ndev, 0, RIC0); ravb_write(ndev, 0, RIC0);
...@@ -2402,7 +2609,8 @@ static int ravb_wol_setup(struct net_device *ndev) ...@@ -2402,7 +2609,8 @@ static int ravb_wol_setup(struct net_device *ndev)
/* Only allow ECI interrupts */ /* Only allow ECI interrupts */
synchronize_irq(priv->emac_irq); synchronize_irq(priv->emac_irq);
napi_disable(&priv->napi[RAVB_NC]); if (info->nc_queue)
napi_disable(&priv->napi[RAVB_NC]);
napi_disable(&priv->napi[RAVB_BE]); napi_disable(&priv->napi[RAVB_BE]);
ravb_write(ndev, ECSIPR_MPDIP, ECSIPR); ravb_write(ndev, ECSIPR_MPDIP, ECSIPR);
...@@ -2415,9 +2623,11 @@ static int ravb_wol_setup(struct net_device *ndev) ...@@ -2415,9 +2623,11 @@ static int ravb_wol_setup(struct net_device *ndev)
static int ravb_wol_restore(struct net_device *ndev) static int ravb_wol_restore(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;
int ret; int ret;
napi_enable(&priv->napi[RAVB_NC]); if (info->nc_queue)
napi_enable(&priv->napi[RAVB_NC]);
napi_enable(&priv->napi[RAVB_BE]); napi_enable(&priv->napi[RAVB_BE]);
/* Disable MagicPacket */ /* Disable MagicPacket */
...@@ -2468,13 +2678,15 @@ static int __maybe_unused ravb_resume(struct device *dev) ...@@ -2468,13 +2678,15 @@ static int __maybe_unused ravb_resume(struct device *dev)
/* Set AVB config mode */ /* Set AVB config mode */
ravb_set_config_mode(ndev); ravb_set_config_mode(ndev);
/* Set GTI value */ if (info->gptp || info->ccc_gac) {
ret = ravb_set_gti(ndev); /* Set GTI value */
if (ret) ret = ravb_set_gti(ndev);
return ret; if (ret)
return ret;
/* Request GTI loading */ /* Request GTI loading */
ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI); ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
}
if (info->internal_delay) if (info->internal_delay)
ravb_set_delay_mode(ndev); ravb_set_delay_mode(ndev);
......
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