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: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2021-10-02 13:52:46 +01:00
commit cfb5d7b781
2 changed files with 362 additions and 129 deletions

View File

@ -81,6 +81,7 @@ enum ravb_reg {
RQC3 = 0x00A0,
RQC4 = 0x00A4,
RPC = 0x00B0,
RTC = 0x00B4, /* R-Car Gen3 and RZ/G2L only */
UFCW = 0x00BC,
UFCS = 0x00C0,
UFCV0 = 0x00C4,
@ -187,13 +188,14 @@ enum ravb_reg {
PIR = 0x0520,
PSR = 0x0528,
PIPR = 0x052c,
CXR31 = 0x0530, /* RZ/G2L only */
MPR = 0x0558,
PFTCR = 0x055c,
PFRCR = 0x0560,
GECMR = 0x05b0,
MAHR = 0x05c0,
MALR = 0x05c8,
TROCR = 0x0700, /* R-Car Gen3 only */
TROCR = 0x0700, /* R-Car Gen3 and RZ/G2L only */
CEFCR = 0x0740,
FRECR = 0x0748,
TSFRCR = 0x0750,
@ -810,10 +812,11 @@ enum ECMR_BIT {
ECMR_TXF = 0x00010000, /* Documented for R-Car Gen3 only */
ECMR_RXF = 0x00020000,
ECMR_PFR = 0x00040000,
ECMR_ZPF = 0x00080000, /* Documented for R-Car Gen3 only */
ECMR_ZPF = 0x00080000, /* Documented for R-Car Gen3 and RZ/G2L */
ECMR_RZPF = 0x00100000,
ECMR_DPAD = 0x00200000,
ECMR_RCSC = 0x00800000,
ECMR_RCPT = 0x02000000, /* Documented for RZ/G2L only */
ECMR_TRCCM = 0x04000000,
};
@ -823,6 +826,7 @@ enum ECSR_BIT {
ECSR_MPD = 0x00000002,
ECSR_LCHNG = 0x00000004,
ECSR_PHYI = 0x00000008,
ECSR_PFRI = 0x00000010,
};
/* ECSIPR */
@ -857,9 +861,13 @@ enum MPR_BIT {
/* GECMR */
enum GECMR_BIT {
GECMR_SPEED = 0x00000001,
GECMR_SPEED_100 = 0x00000000,
GECMR_SPEED_1000 = 0x00000001,
GECMR_SPEED = 0x00000001,
GECMR_SPEED_100 = 0x00000000,
GECMR_SPEED_1000 = 0x00000001,
GBETH_GECMR_SPEED = 0x00000030,
GBETH_GECMR_SPEED_10 = 0x00000000,
GBETH_GECMR_SPEED_100 = 0x00000010,
GBETH_GECMR_SPEED_1000 = 0x00000020,
};
/* The Ethernet AVB descriptor definitions. */
@ -949,6 +957,11 @@ enum RAVB_QUEUE {
RAVB_NC, /* Network Control Queue */
};
enum CXR31_BIT {
CXR31_SEL_LINK0 = 0x00000001,
CXR31_SEL_LINK1 = 0x00000008,
};
#define DBAT_ENTRY_NUM 22
#define RX_QUEUE_OFFSET 4
#define NUM_RX_QUEUE 2
@ -956,6 +969,8 @@ enum RAVB_QUEUE {
#define RX_BUF_SZ (2048 - ETH_FCS_LEN + sizeof(__sum16))
#define GBETH_RX_BUFF_MAX 8192
struct ravb_tstamp_skb {
struct list_head list;
struct sk_buff *skb;
@ -985,8 +1000,8 @@ struct ravb_hw_info {
void *(*alloc_rx_desc)(struct net_device *ndev, int q);
bool (*receive)(struct net_device *ndev, int *quota, int q);
void (*set_rate)(struct net_device *ndev);
int (*set_rx_csum_feature)(struct net_device *ndev, netdev_features_t features);
void (*dmac_init)(struct net_device *ndev);
int (*set_feature)(struct net_device *ndev, netdev_features_t features);
int (*dmac_init)(struct net_device *ndev);
void (*emac_init)(struct net_device *ndev);
const char (*gstrings_stats)[ETH_GSTRING_LEN];
size_t gstrings_size;
@ -994,14 +1009,18 @@ struct ravb_hw_info {
netdev_features_t net_features;
int stats_len;
size_t max_rx_len;
u32 tsrq;
unsigned aligned_tx: 1;
/* hardware features */
unsigned internal_delay:1; /* AVB-DMAC has internal delays */
unsigned tx_counters:1; /* E-MAC has TX counters */
unsigned multi_irqs:1; /* AVB-DMAC and E-MAC has multiple irqs */
unsigned no_ptp_cfg_active:1; /* AVB-DMAC does not support gPTP active in config mode */
unsigned ptp_cfg_active:1; /* AVB-DMAC has gPTP support active in config mode */
unsigned gptp:1; /* AVB-DMAC has gPTP support */
unsigned ccc_gac:1; /* AVB-DMAC has gPTP support active in config mode */
unsigned nc_queue:1; /* AVB-DMAC has NC queue */
unsigned magic_pkt:1; /* E-MAC supports magic packet detection */
unsigned half_duplex:1; /* E-MAC supports half duplex mode */
};
struct ravb_private {
@ -1056,6 +1075,8 @@ struct ravb_private {
unsigned rgmii_override:1; /* Deprecated rgmii-*id behavior */
unsigned int num_tx_desc; /* TX descriptors per packet */
int duplex;
const struct ravb_hw_info *info;
struct reset_control *rstc;
};

View File

@ -83,7 +83,24 @@ static int ravb_config(struct net_device *ndev)
return error;
}
static void ravb_set_rate(struct net_device *ndev)
static void ravb_set_rate_gbeth(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
switch (priv->speed) {
case 10: /* 10BASE */
ravb_write(ndev, GBETH_GECMR_SPEED_10, GECMR);
break;
case 100: /* 100BASE */
ravb_write(ndev, GBETH_GECMR_SPEED_100, GECMR);
break;
case 1000: /* 1000BASE */
ravb_write(ndev, GBETH_GECMR_SPEED_1000, GECMR);
break;
}
}
static void ravb_set_rate_rcar(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
@ -217,6 +234,11 @@ static int ravb_tx_free(struct net_device *ndev, int q, bool free_txed_only)
return free_num;
}
static void ravb_rx_ring_free_gbeth(struct net_device *ndev, int q)
{
/* Place holder */
}
static void ravb_rx_ring_free(struct net_device *ndev, int q)
{
struct ravb_private *priv = netdev_priv(ndev);
@ -283,6 +305,11 @@ static void ravb_ring_free(struct net_device *ndev, int q)
priv->tx_skb[q] = NULL;
}
static void ravb_rx_ring_format_gbeth(struct net_device *ndev, int q)
{
/* Place holder */
}
static void ravb_rx_ring_format(struct net_device *ndev, int q)
{
struct ravb_private *priv = netdev_priv(ndev);
@ -356,6 +383,12 @@ static void ravb_ring_format(struct net_device *ndev, int q)
desc->dptr = cpu_to_le32((u32)priv->tx_desc_dma[q]);
}
static void *ravb_alloc_rx_desc_gbeth(struct net_device *ndev, int q)
{
/* Place holder */
return NULL;
}
static void *ravb_alloc_rx_desc(struct net_device *ndev, int q)
{
struct ravb_private *priv = netdev_priv(ndev);
@ -426,7 +459,37 @@ error:
return -ENOMEM;
}
static void ravb_rcar_emac_init(struct net_device *ndev)
static void ravb_emac_init_gbeth(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
/* Receive frame limit set register */
ravb_write(ndev, GBETH_RX_BUFF_MAX + ETH_FCS_LEN, RFLR);
/* PAUSE prohibition */
ravb_write(ndev, ECMR_ZPF | ((priv->duplex > 0) ? ECMR_DM : 0) |
ECMR_TE | ECMR_RE | ECMR_RCPT |
ECMR_TXF | ECMR_RXF | ECMR_PRM, ECMR);
ravb_set_rate_gbeth(ndev);
/* Set MAC address */
ravb_write(ndev,
(ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
(ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), MAHR);
ravb_write(ndev, (ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), MALR);
/* E-MAC status register clear */
ravb_write(ndev, ECSR_ICD | ECSR_LCHNG | ECSR_PFRI, ECSR);
/* E-MAC interrupt enable register */
ravb_write(ndev, ECSIPR_ICDIP, ECSIPR);
ravb_modify(ndev, CXR31, CXR31_SEL_LINK1, 0);
ravb_modify(ndev, CXR31, CXR31_SEL_LINK0, CXR31_SEL_LINK0);
}
static void ravb_emac_init_rcar(struct net_device *ndev)
{
/* Receive frame limit set register */
ravb_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN, RFLR);
@ -436,7 +499,7 @@ static void ravb_rcar_emac_init(struct net_device *ndev)
(ndev->features & NETIF_F_RXCSUM ? ECMR_RCSC : 0) |
ECMR_TE | ECMR_RE, ECMR);
ravb_set_rate(ndev);
ravb_set_rate_rcar(ndev);
/* Set MAC address */
ravb_write(ndev,
@ -461,10 +524,58 @@ static void ravb_emac_init(struct net_device *ndev)
info->emac_init(ndev);
}
static void ravb_rcar_dmac_init(struct net_device *ndev)
static int ravb_dmac_init_gbeth(struct net_device *ndev)
{
int error;
error = ravb_ring_init(ndev, RAVB_BE);
if (error)
return error;
/* Descriptor format */
ravb_ring_format(ndev, RAVB_BE);
/* Set AVB RX */
ravb_write(ndev, 0x60000000, RCR);
/* Set Max Frame Length (RTC) */
ravb_write(ndev, 0x7ffc0000 | GBETH_RX_BUFF_MAX, RTC);
/* Set FIFO size */
ravb_write(ndev, 0x00222200, TGC);
ravb_write(ndev, 0, TCCR);
/* Frame receive */
ravb_write(ndev, RIC0_FRE0, RIC0);
/* Disable FIFO full warning */
ravb_write(ndev, 0x0, RIC1);
/* Receive FIFO full error, descriptor empty */
ravb_write(ndev, RIC2_QFE0 | RIC2_RFFE, RIC2);
ravb_write(ndev, TIC_FTE0, TIC);
return 0;
}
static int ravb_dmac_init_rcar(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
int error;
error = ravb_ring_init(ndev, RAVB_BE);
if (error)
return error;
error = ravb_ring_init(ndev, RAVB_NC);
if (error) {
ravb_ring_free(ndev, RAVB_BE);
return error;
}
/* Descriptor format */
ravb_ring_format(ndev, RAVB_BE);
ravb_ring_format(ndev, RAVB_NC);
/* Set AVB RX */
ravb_write(ndev,
@ -491,6 +602,8 @@ static void ravb_rcar_dmac_init(struct net_device *ndev)
ravb_write(ndev, RIC2_QFE0 | RIC2_QFE1 | RIC2_RFFE, RIC2);
/* Frame transmitted, timestamp FIFO updated */
ravb_write(ndev, TIC_FTE0 | TIC_FTE1 | TIC_TFUE, TIC);
return 0;
}
/* Device init function for Ethernet AVB */
@ -505,20 +618,9 @@ static int ravb_dmac_init(struct net_device *ndev)
if (error)
return error;
error = ravb_ring_init(ndev, RAVB_BE);
error = info->dmac_init(ndev);
if (error)
return error;
error = ravb_ring_init(ndev, RAVB_NC);
if (error) {
ravb_ring_free(ndev, RAVB_BE);
return error;
}
/* Descriptor format */
ravb_ring_format(ndev, RAVB_BE);
ravb_ring_format(ndev, RAVB_NC);
info->dmac_init(ndev);
/* Setting the control will start the AVB-DMAC process. */
ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_OPERATION);
@ -579,6 +681,14 @@ static void ravb_rx_csum(struct sk_buff *skb)
skb_trim(skb, skb->len - sizeof(__sum16));
}
/* Packet receive function for Gigabit Ethernet */
static bool ravb_rx_gbeth(struct net_device *ndev, int *quota, int q)
{
/* Place holder */
return true;
}
/* Packet receive function for Ethernet AVB */
static bool ravb_rcar_rx(struct net_device *ndev, int *quota, int q)
{
struct ravb_private *priv = netdev_priv(ndev);
@ -717,11 +827,13 @@ static void ravb_rcv_snd_enable(struct net_device *ndev)
/* function for waiting dma process finished */
static int ravb_stop_dma(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
int error;
/* Wait for stopping the hardware TX process */
error = ravb_wait(ndev, TCCR,
TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3, 0);
error = ravb_wait(ndev, TCCR, info->tsrq, 0);
if (error)
return error;
@ -859,6 +971,7 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
{
struct net_device *ndev = dev_id;
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
irqreturn_t result = IRQ_NONE;
u32 iss;
@ -875,8 +988,13 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
result = IRQ_HANDLED;
/* Network control and best effort queue RX/TX */
for (q = RAVB_NC; q >= RAVB_BE; q--) {
if (ravb_queue_interrupt(ndev, q))
if (info->nc_queue) {
for (q = RAVB_NC; q >= RAVB_BE; q--) {
if (ravb_queue_interrupt(ndev, q))
result = IRQ_HANDLED;
}
} else {
if (ravb_queue_interrupt(ndev, RAVB_BE))
result = IRQ_HANDLED;
}
}
@ -1000,7 +1118,8 @@ static int ravb_poll(struct napi_struct *napi, int budget)
/* Receive error message handling */
priv->rx_over_errors = priv->stats[RAVB_BE].rx_over_errors;
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)
ndev->stats.rx_over_errors = priv->rx_over_errors;
if (priv->rx_fifo_errors != ndev->stats.rx_fifo_errors)
@ -1009,6 +1128,13 @@ out:
return budget - quota;
}
static void ravb_set_duplex_gbeth(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
ravb_modify(ndev, ECMR, ECMR_DM, priv->duplex > 0 ? ECMR_DM : 0);
}
/* PHY state control function */
static void ravb_adjust_link(struct net_device *ndev)
{
@ -1025,6 +1151,12 @@ static void ravb_adjust_link(struct net_device *ndev)
ravb_rcv_snd_disable(ndev);
if (phydev->link) {
if (info->half_duplex && phydev->duplex != priv->duplex) {
new_state = true;
priv->duplex = phydev->duplex;
ravb_set_duplex_gbeth(ndev);
}
if (phydev->speed != priv->speed) {
new_state = true;
priv->speed = phydev->speed;
@ -1039,6 +1171,8 @@ static void ravb_adjust_link(struct net_device *ndev)
new_state = true;
priv->link = 0;
priv->speed = 0;
if (info->half_duplex)
priv->duplex = -1;
}
/* Enable TX and RX right over here, if E-MAC change is ignored */
@ -1061,6 +1195,7 @@ static int ravb_phy_init(struct net_device *ndev)
{
struct device_node *np = ndev->dev.parent->of_node;
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
struct phy_device *phydev;
struct device_node *pn;
phy_interface_t iface;
@ -1068,6 +1203,7 @@ static int ravb_phy_init(struct net_device *ndev)
priv->link = 0;
priv->speed = 0;
priv->duplex = -1;
/* Try connecting to PHY */
pn = of_parse_phandle(np, "phy-handle", 0);
@ -1106,15 +1242,17 @@ static int ravb_phy_init(struct net_device *ndev)
netdev_info(ndev, "limited PHY to 100Mbit/s\n");
}
/* 10BASE, Pause and Asym Pause is not supported */
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Pause_BIT);
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT);
if (!info->half_duplex) {
/* 10BASE, Pause and Asym Pause is not supported */
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
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 */
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
/* Half Duplex is not supported */
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
}
phy_attached_info(phydev);
@ -1208,11 +1346,14 @@ static void ravb_get_ethtool_stats(struct net_device *ndev,
struct ethtool_stats *estats, u64 *data)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
int num_rx_q;
int i = 0;
int q;
num_rx_q = info->nc_queue ? NUM_RX_QUEUE : 1;
/* Device-specific stats */
for (q = RAVB_BE; q < NUM_RX_QUEUE; q++) {
for (q = RAVB_BE; q < num_rx_q; q++) {
struct net_device_stats *stats = &priv->stats[q];
data[i++] = priv->cur_rx[q];
@ -1274,7 +1415,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
if (netif_running(ndev)) {
netif_device_detach(ndev);
/* Stop PTP Clock driver */
if (info->no_ptp_cfg_active)
if (info->gptp)
ravb_ptp_stop(ndev);
/* Wait for DMA stopping */
error = ravb_stop_dma(ndev);
@ -1287,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. */
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 */
@ -1306,7 +1448,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
ravb_emac_init(ndev);
/* Initialise PTP Clock driver */
if (info->no_ptp_cfg_active)
if (info->gptp)
ravb_ptp_init(ndev, priv->pdev);
netif_device_attach(ndev);
@ -1319,6 +1461,7 @@ static int ravb_get_ts_info(struct net_device *ndev,
struct ethtool_ts_info *info)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *hw_info = priv->info;
info->so_timestamping =
SOF_TIMESTAMPING_TX_SOFTWARE |
@ -1332,7 +1475,8 @@ static int ravb_get_ts_info(struct net_device *ndev,
(1 << HWTSTAMP_FILTER_NONE) |
(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
(1 << HWTSTAMP_FILTER_ALL);
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;
}
@ -1348,8 +1492,9 @@ static void ravb_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
static int ravb_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
if (wol->wolopts & ~WAKE_MAGIC)
if (!info->magic_pkt || (wol->wolopts & ~WAKE_MAGIC))
return -EOPNOTSUPP;
priv->wol_enabled = !!(wol->wolopts & WAKE_MAGIC);
@ -1403,7 +1548,8 @@ static int ravb_open(struct net_device *ndev)
int error;
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) {
error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED,
@ -1446,7 +1592,7 @@ static int ravb_open(struct net_device *ndev)
ravb_emac_init(ndev);
/* Initialise PTP Clock driver */
if (info->no_ptp_cfg_active)
if (info->gptp)
ravb_ptp_init(ndev, priv->pdev);
netif_tx_start_all_queues(ndev);
@ -1460,7 +1606,7 @@ static int ravb_open(struct net_device *ndev)
out_ptp_stop:
/* Stop PTP Clock driver */
if (info->no_ptp_cfg_active)
if (info->gptp)
ravb_ptp_stop(ndev);
out_free_irq_nc_tx:
if (!info->multi_irqs)
@ -1477,7 +1623,8 @@ out_free_irq_emac:
out_free_irq:
free_irq(ndev->irq, ndev);
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]);
return error;
}
@ -1508,7 +1655,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
netif_tx_stop_all_queues(ndev);
/* Stop PTP Clock driver */
if (info->no_ptp_cfg_active)
if (info->gptp)
ravb_ptp_stop(ndev);
/* Wait for DMA stopping */
@ -1526,7 +1673,8 @@ static void ravb_tx_timeout_work(struct work_struct *work)
}
ravb_ring_free(ndev, RAVB_BE);
ravb_ring_free(ndev, RAVB_NC);
if (info->nc_queue)
ravb_ring_free(ndev, RAVB_NC);
/* Device init */
error = ravb_dmac_init(ndev);
@ -1543,7 +1691,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
out:
/* Initialise PTP Clock driver */
if (info->no_ptp_cfg_active)
if (info->gptp)
ravb_ptp_init(ndev, priv->pdev);
netif_tx_start_all_queues(ndev);
@ -1553,6 +1701,7 @@ out:
static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
unsigned int num_tx_desc = priv->num_tx_desc;
u16 q = skb_get_queue_mapping(skb);
struct ravb_tstamp_skb *ts_skb;
@ -1629,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);
/* TX timestamp required */
if (q == RAVB_NC) {
ts_skb = kmalloc(sizeof(*ts_skb), GFP_ATOMIC);
if (!ts_skb) {
if (num_tx_desc > 1) {
desc--;
dma_unmap_single(ndev->dev.parent, dma_addr,
len, DMA_TO_DEVICE);
if (info->gptp || info->ccc_gac) {
if (q == RAVB_NC) {
ts_skb = kmalloc(sizeof(*ts_skb), GFP_ATOMIC);
if (!ts_skb) {
if (num_tx_desc > 1) {
desc--;
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_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);
}
skb_tx_timestamp(skb);
/* Descriptor type must be set after all the above writes */
dma_wmb();
if (num_tx_desc > 1) {
@ -1698,28 +1849,38 @@ static struct net_device_stats *ravb_get_stats(struct net_device *ndev)
nstats = &ndev->stats;
stats0 = &priv->stats[RAVB_BE];
stats1 = &priv->stats[RAVB_NC];
if (info->tx_counters) {
nstats->tx_dropped += ravb_read(ndev, TROCR);
ravb_write(ndev, 0, TROCR); /* (write clear) */
}
nstats->rx_packets = stats0->rx_packets + stats1->rx_packets;
nstats->tx_packets = stats0->tx_packets + stats1->tx_packets;
nstats->rx_bytes = stats0->rx_bytes + stats1->rx_bytes;
nstats->tx_bytes = stats0->tx_bytes + stats1->tx_bytes;
nstats->multicast = stats0->multicast + stats1->multicast;
nstats->rx_errors = stats0->rx_errors + stats1->rx_errors;
nstats->rx_crc_errors = stats0->rx_crc_errors + stats1->rx_crc_errors;
nstats->rx_frame_errors =
stats0->rx_frame_errors + stats1->rx_frame_errors;
nstats->rx_length_errors =
stats0->rx_length_errors + stats1->rx_length_errors;
nstats->rx_missed_errors =
stats0->rx_missed_errors + stats1->rx_missed_errors;
nstats->rx_over_errors =
stats0->rx_over_errors + stats1->rx_over_errors;
nstats->rx_packets = stats0->rx_packets;
nstats->tx_packets = stats0->tx_packets;
nstats->rx_bytes = stats0->rx_bytes;
nstats->tx_bytes = stats0->tx_bytes;
nstats->multicast = stats0->multicast;
nstats->rx_errors = stats0->rx_errors;
nstats->rx_crc_errors = stats0->rx_crc_errors;
nstats->rx_frame_errors = stats0->rx_frame_errors;
nstats->rx_length_errors = stats0->rx_length_errors;
nstats->rx_missed_errors = stats0->rx_missed_errors;
nstats->rx_over_errors = stats0->rx_over_errors;
if (info->nc_queue) {
stats1 = &priv->stats[RAVB_NC];
nstats->rx_packets += stats1->rx_packets;
nstats->tx_packets += stats1->tx_packets;
nstats->rx_bytes += stats1->rx_bytes;
nstats->tx_bytes += stats1->tx_bytes;
nstats->multicast += stats1->multicast;
nstats->rx_errors += stats1->rx_errors;
nstats->rx_crc_errors += stats1->rx_crc_errors;
nstats->rx_frame_errors += stats1->rx_frame_errors;
nstats->rx_length_errors += stats1->rx_length_errors;
nstats->rx_missed_errors += stats1->rx_missed_errors;
nstats->rx_over_errors += stats1->rx_over_errors;
}
return nstats;
}
@ -1752,7 +1913,7 @@ static int ravb_close(struct net_device *ndev)
ravb_write(ndev, 0, TIC);
/* Stop PTP Clock driver */
if (info->no_ptp_cfg_active)
if (info->gptp)
ravb_ptp_stop(ndev);
/* Set the config mode to stop the AVB-DMAC's processes */
@ -1761,10 +1922,12 @@ static int ravb_close(struct net_device *ndev)
"device will be stopped after h/w processes are done.\n");
/* Clear the timestamp list */
list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) {
list_del(&ts_skb->list);
kfree_skb(ts_skb->skb);
kfree(ts_skb);
if (info->gptp || info->ccc_gac) {
list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) {
list_del(&ts_skb->list);
kfree_skb(ts_skb->skb);
kfree(ts_skb);
}
}
/* PHY disconnect */
@ -1784,12 +1947,14 @@ static int ravb_close(struct net_device *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]);
/* Free all the skb's in the RX queue and the DMA buffers. */
ravb_ring_free(ndev, RAVB_BE);
ravb_ring_free(ndev, RAVB_NC);
if (info->nc_queue)
ravb_ring_free(ndev, RAVB_NC);
return 0;
}
@ -1918,8 +2083,15 @@ static void ravb_set_rx_csum(struct net_device *ndev, bool enable)
spin_unlock_irqrestore(&priv->lock, flags);
}
static int ravb_set_features_rx_csum(struct net_device *ndev,
netdev_features_t features)
static int ravb_set_features_gbeth(struct net_device *ndev,
netdev_features_t features)
{
/* Place holder */
return 0;
}
static int ravb_set_features_rcar(struct net_device *ndev,
netdev_features_t features)
{
netdev_features_t changed = ndev->features ^ features;
@ -1937,7 +2109,7 @@ static int ravb_set_features(struct net_device *ndev,
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
return info->set_rx_csum_feature(ndev, features);
return info->set_feature(ndev, features);
}
static const struct net_device_ops ravb_netdev_ops = {
@ -2005,20 +2177,23 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
.rx_ring_format = ravb_rx_ring_format,
.alloc_rx_desc = ravb_alloc_rx_desc,
.receive = ravb_rcar_rx,
.set_rate = ravb_set_rate,
.set_rx_csum_feature = ravb_set_features_rx_csum,
.dmac_init = ravb_rcar_dmac_init,
.emac_init = ravb_rcar_emac_init,
.set_rate = ravb_set_rate_rcar,
.set_feature = ravb_set_features_rcar,
.dmac_init = ravb_dmac_init_rcar,
.emac_init = ravb_emac_init_rcar,
.gstrings_stats = ravb_gstrings_stats,
.gstrings_size = sizeof(ravb_gstrings_stats),
.net_hw_features = NETIF_F_RXCSUM,
.net_features = NETIF_F_RXCSUM,
.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
.tsrq = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
.internal_delay = 1,
.tx_counters = 1,
.multi_irqs = 1,
.ptp_cfg_active = 1,
.ccc_gac = 1,
.nc_queue = 1,
.magic_pkt = 1,
};
static const struct ravb_hw_info ravb_gen2_hw_info = {
@ -2026,18 +2201,37 @@ static const struct ravb_hw_info ravb_gen2_hw_info = {
.rx_ring_format = ravb_rx_ring_format,
.alloc_rx_desc = ravb_alloc_rx_desc,
.receive = ravb_rcar_rx,
.set_rate = ravb_set_rate,
.set_rx_csum_feature = ravb_set_features_rx_csum,
.dmac_init = ravb_rcar_dmac_init,
.emac_init = ravb_rcar_emac_init,
.set_rate = ravb_set_rate_rcar,
.set_feature = ravb_set_features_rcar,
.dmac_init = ravb_dmac_init_rcar,
.emac_init = ravb_emac_init_rcar,
.gstrings_stats = ravb_gstrings_stats,
.gstrings_size = sizeof(ravb_gstrings_stats),
.net_hw_features = NETIF_F_RXCSUM,
.net_features = NETIF_F_RXCSUM,
.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
.tsrq = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
.aligned_tx = 1,
.no_ptp_cfg_active = 1,
.gptp = 1,
.nc_queue = 1,
.magic_pkt = 1,
};
static const struct ravb_hw_info gbeth_hw_info = {
.rx_ring_free = ravb_rx_ring_free_gbeth,
.rx_ring_format = ravb_rx_ring_format_gbeth,
.alloc_rx_desc = ravb_alloc_rx_desc_gbeth,
.receive = ravb_rx_gbeth,
.set_rate = ravb_set_rate_gbeth,
.set_feature = ravb_set_features_gbeth,
.dmac_init = ravb_dmac_init_gbeth,
.emac_init = ravb_emac_init_gbeth,
.max_rx_len = GBETH_RX_BUFF_MAX + RAVB_ALIGN - 1,
.tsrq = TCCR_TSRQ0,
.aligned_tx = 1,
.tx_counters = 1,
.half_duplex = 1,
};
static const struct of_device_id ravb_match_table[] = {
@ -2046,6 +2240,7 @@ static const struct of_device_id ravb_match_table[] = {
{ .compatible = "renesas,etheravb-rcar-gen2", .data = &ravb_gen2_hw_info },
{ .compatible = "renesas,etheravb-r8a7795", .data = &ravb_gen3_hw_info },
{ .compatible = "renesas,etheravb-rcar-gen3", .data = &ravb_gen3_hw_info },
{ .compatible = "renesas,rzg2l-gbeth", .data = &gbeth_hw_info },
{ }
};
MODULE_DEVICE_TABLE(of, ravb_match_table);
@ -2080,13 +2275,15 @@ static void ravb_set_config_mode(struct net_device *ndev)
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
if (info->no_ptp_cfg_active) {
if (info->gptp) {
ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG);
/* Set CSEL value */
ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB);
} else {
} else if (info->ccc_gac) {
ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG |
CCC_GAC | CCC_CSEL_HPB);
} else {
ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG);
}
}
@ -2192,8 +2389,11 @@ static int ravb_probe(struct platform_device *pdev)
priv->pdev = pdev;
priv->num_tx_ring[RAVB_BE] = BE_TX_RING_SIZE;
priv->num_rx_ring[RAVB_BE] = BE_RX_RING_SIZE;
priv->num_tx_ring[RAVB_NC] = NC_TX_RING_SIZE;
priv->num_rx_ring[RAVB_NC] = NC_RX_RING_SIZE;
if (info->nc_queue) {
priv->num_tx_ring[RAVB_NC] = NC_TX_RING_SIZE;
priv->num_rx_ring[RAVB_NC] = NC_RX_RING_SIZE;
}
priv->addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(priv->addr)) {
error = PTR_ERR(priv->addr);
@ -2269,13 +2469,15 @@ static int ravb_probe(struct platform_device *pdev)
/* Set AVB config mode */
ravb_set_config_mode(ndev);
/* Set GTI value */
error = ravb_set_gti(ndev);
if (error)
goto out_disable_refclk;
if (info->gptp || info->ccc_gac) {
/* Set GTI value */
error = ravb_set_gti(ndev);
if (error)
goto out_disable_refclk;
/* Request GTI loading */
ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
/* Request GTI loading */
ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
}
if (info->internal_delay) {
ravb_parse_delay_mode(np, ndev);
@ -2301,7 +2503,7 @@ static int ravb_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&priv->ts_skb_list);
/* Initialise PTP Clock driver */
if (info->ptp_cfg_active)
if (info->ccc_gac)
ravb_ptp_init(ndev, pdev);
/* Debug message level */
@ -2323,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_NC], ravb_poll, 64);
if (info->nc_queue)
netif_napi_add(ndev, &priv->napi[RAVB_NC], ravb_poll, 64);
/* Network device register */
error = register_netdev(ndev);
@ -2341,7 +2544,9 @@ static int ravb_probe(struct platform_device *pdev)
return 0;
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]);
ravb_mdio_release(priv);
out_dma_free:
@ -2349,7 +2554,7 @@ out_dma_free:
priv->desc_bat_dma);
/* Stop PTP Clock driver */
if (info->ptp_cfg_active)
if (info->ccc_gac)
ravb_ptp_stop(ndev);
out_disable_refclk:
clk_disable_unprepare(priv->refclk);
@ -2369,7 +2574,7 @@ static int ravb_remove(struct platform_device *pdev)
const struct ravb_hw_info *info = priv->info;
/* Stop PTP Clock driver */
if (info->ptp_cfg_active)
if (info->ccc_gac)
ravb_ptp_stop(ndev);
clk_disable_unprepare(priv->refclk);
@ -2380,7 +2585,8 @@ static int ravb_remove(struct platform_device *pdev)
ravb_write(ndev, CCC_OPC_RESET, CCC);
pm_runtime_put_sync(&pdev->dev);
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]);
ravb_mdio_release(priv);
pm_runtime_disable(&pdev->dev);
@ -2394,6 +2600,7 @@ static int ravb_remove(struct platform_device *pdev)
static int ravb_wol_setup(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
/* Disable interrupts by clearing the interrupt masks. */
ravb_write(ndev, 0, RIC0);
@ -2402,7 +2609,8 @@ static int ravb_wol_setup(struct net_device *ndev)
/* Only allow ECI interrupts */
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]);
ravb_write(ndev, ECSIPR_MPDIP, ECSIPR);
@ -2415,9 +2623,11 @@ static int ravb_wol_setup(struct net_device *ndev)
static int ravb_wol_restore(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
int ret;
napi_enable(&priv->napi[RAVB_NC]);
if (info->nc_queue)
napi_enable(&priv->napi[RAVB_NC]);
napi_enable(&priv->napi[RAVB_BE]);
/* Disable MagicPacket */
@ -2468,13 +2678,15 @@ static int __maybe_unused ravb_resume(struct device *dev)
/* Set AVB config mode */
ravb_set_config_mode(ndev);
/* Set GTI value */
ret = ravb_set_gti(ndev);
if (ret)
return ret;
if (info->gptp || info->ccc_gac) {
/* Set GTI value */
ret = ravb_set_gti(ndev);
if (ret)
return ret;
/* Request GTI loading */
ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
/* Request GTI loading */
ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
}
if (info->internal_delay)
ravb_set_delay_mode(ndev);