forked from Minki/linux
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:
commit
cfb5d7b781
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user