Driver specific changes

Again, a lot of platforms have changes in here: pxa, samsung, omap,
 at91, imx, ...
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIVAwUATwtZUmCrR//JCVInAQL93hAAzBbSkswA4SD09UXHPSLGpbWd7JYuax9T
 sR17FvnQCV+0T8c7ORRbjoBrCrxKkxuPMkFrfIHuTaP+beYe13CwTf2mV+dtnuv2
 hSjSjdgCq+yv+CvRZhRnmHqmEePN1dvRoC9Q/EVPEibJNJ4BjrTALMfkXbsTz861
 BOmcD7VGi0YfPhwRQ3D00MjohCflRoV2EmceHCUvH4HLEgpWcWl16UZeuWGn6BiA
 GJK37O2ubKz0hkExAH6NHEaRxeFsapjh8kkR8/dOoNh/iIlmmR5SRPOxMPWFD0ui
 lUeSc6QjMipHCzkfE7jUx6MICDZfRx+WRWVTwa/OTLJjJtY+zcRnUvoLl84XJqgX
 EG5YhyL+Os4Z0ci92uSK3rwYQ2AJz/r4dS6VWnAVVJHSc8zHCuioJL4KcF81llcz
 1dshlHkB1H1EeVrf08OM/1xX0X7SNzVJlQ801OZj31DYYtMqvrev72vn+tvJh6kL
 o9gZsOSl3cIlFi8cAK0WmZmwGHw4wfUDZb1ojN6GDctdrp/Vmwe3exHleWvfSDtN
 QBw4WyHl46JGw4bFVQ4hRH3vJZNuiso+ZNZvG3qGaEMfpNY5aMTy7lrxI/GFbFkA
 tEnhkDgjutEZ/B6nEF1h8cCrcLND7u4n209kJh6UR1Qx3a6xD/M/ycE4tisNuPE3
 wSSYuM1ZGTU=
 =vPhu
 -----END PGP SIGNATURE-----

Merge tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Driver specific changes

Again, a lot of platforms have changes in here: pxa, samsung, omap,
at91, imx, ...

* tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (54 commits)
  ARM: sa1100: clean up of the clock support
  ARM: pxa: add dummy clock for sa1100-rtc
  RTC: sa1100: support sa1100, pxa and mmp soc families
  RTC: sa1100: remove redundant code of setting alarm
  RTC: sa1100: Clean out ost register
  Input: zylonite-wm97xx - replace IRQ_GPIO() with gpio_to_irq()
  pcmcia: pxa: replace IRQ_GPIO() with gpio_to_irq()
  ARM: EXYNOS: Modified files for SPI consolidation work
  ARM: S5P64X0: Enable SDHCI support
  ARM: S5P64X0: Add lookup of sdhci-s3c clocks using generic names
  ARM: S5P64X0: Add HSMMC setup for host Controller
  ARM: EXYNOS: Add USB OHCI support to ORIGEN board
  USB: Add Samsung Exynos OHCI diver
  ARM: EXYNOS: Add USB OHCI support to SMDKV310 board
  ARM: EXYNOS: Add USB OHCI device
  net: macb: fix build break with !CONFIG_OF
  i2c: tegra: Support DVC controller in device tree
  i2c: tegra: Add __devinit/exit to probe/remove
  net/at91_ether: use gpio_is_valid for phy IRQ line
  ARM: at91/net: add macb ethernet controller in 9g45/9g20 DT
  ...
This commit is contained in:
Linus Torvalds 2012-01-09 14:39:22 -08:00
commit 2ac9d7aacc
169 changed files with 3010 additions and 1631 deletions

View file

@ -10,7 +10,7 @@ obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
obj-$(CONFIG_NET_VENDOR_AMD) += amd/
obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
obj-$(CONFIG_NET_ATMEL) += cadence/
obj-$(CONFIG_NET_CADENCE) += cadence/
obj-$(CONFIG_NET_BFIN) += adi/
obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/
obj-$(CONFIG_NET_VENDOR_BROCADE) += brocade/

View file

@ -5,8 +5,8 @@
config HAVE_NET_MACB
bool
config NET_ATMEL
bool "Atmel devices"
config NET_CADENCE
bool "Cadence devices"
default y
depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200)
---help---
@ -21,7 +21,7 @@ config NET_ATMEL
the remaining Atmel network card questions. If you say Y, you will be
asked for your specific card in the following questions.
if NET_ATMEL
if NET_CADENCE
config ARM_AT91_ETHER
tristate "AT91RM9200 Ethernet support"
@ -33,14 +33,16 @@ config ARM_AT91_ETHER
ethernet support, then you should always answer Y to this.
config MACB
tristate "Atmel MACB support"
tristate "Cadence MACB/GEM support"
depends on HAVE_NET_MACB
select PHYLIB
---help---
The Atmel MACB ethernet interface is found on many AT32 and AT91
parts. Say Y to include support for the MACB chip.
The Cadence MACB ethernet interface is found on many Atmel AT32 and
AT91 parts. This driver also supports the Cadence GEM (Gigabit
Ethernet MAC found in some ARM SoC devices). Note: the Gigabit mode
is not yet supported. Say Y to include support for the MACB/GEM chip.
To compile this driver as a module, choose M here: the module
will be called macb.
endif # NET_ATMEL
endif # NET_CADENCE

View file

@ -256,8 +256,7 @@ static void enable_phyirq(struct net_device *dev)
unsigned int dsintr, irq_number;
int status;
irq_number = lp->board_data.phy_irq_pin;
if (!irq_number) {
if (!gpio_is_valid(lp->board_data.phy_irq_pin)) {
/*
* PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L),
* or board does not have it connected.
@ -266,6 +265,7 @@ static void enable_phyirq(struct net_device *dev)
return;
}
irq_number = lp->board_data.phy_irq_pin;
status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev);
if (status) {
printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status);
@ -320,8 +320,7 @@ static void disable_phyirq(struct net_device *dev)
unsigned int dsintr;
unsigned int irq_number;
irq_number = lp->board_data.phy_irq_pin;
if (!irq_number) {
if (!gpio_is_valid(lp->board_data.phy_irq_pin)) {
del_timer_sync(&lp->check_timer);
return;
}
@ -366,6 +365,7 @@ static void disable_phyirq(struct net_device *dev)
disable_mdi();
spin_unlock_irq(&lp->lock);
irq_number = lp->board_data.phy_irq_pin;
free_irq(irq_number, dev); /* Free interrupt handler */
}
@ -1078,7 +1078,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
netif_carrier_off(dev); /* will be enabled in open() */
/* If board has no PHY IRQ, use a timer to poll the PHY */
if (!lp->board_data.phy_irq_pin) {
if (!gpio_is_valid(lp->board_data.phy_irq_pin)) {
init_timer(&lp->check_timer);
lp->check_timer.data = (unsigned long)dev;
lp->check_timer.function = at91ether_check_link;
@ -1170,7 +1170,8 @@ static int __devexit at91ether_remove(struct platform_device *pdev)
struct net_device *dev = platform_get_drvdata(pdev);
struct at91_private *lp = netdev_priv(dev);
if (lp->board_data.phy_irq_pin >= 32)
if (gpio_is_valid(lp->board_data.phy_irq_pin) &&
lp->board_data.phy_irq_pin >= 32)
gpio_free(lp->board_data.phy_irq_pin);
unregister_netdev(dev);
@ -1189,11 +1190,12 @@ static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg)
{
struct net_device *net_dev = platform_get_drvdata(pdev);
struct at91_private *lp = netdev_priv(net_dev);
int phy_irq = lp->board_data.phy_irq_pin;
if (netif_running(net_dev)) {
if (phy_irq)
if (gpio_is_valid(lp->board_data.phy_irq_pin)) {
int phy_irq = lp->board_data.phy_irq_pin;
disable_irq(phy_irq);
}
netif_stop_queue(net_dev);
netif_device_detach(net_dev);
@ -1207,7 +1209,6 @@ static int at91ether_resume(struct platform_device *pdev)
{
struct net_device *net_dev = platform_get_drvdata(pdev);
struct at91_private *lp = netdev_priv(net_dev);
int phy_irq = lp->board_data.phy_irq_pin;
if (netif_running(net_dev)) {
clk_enable(lp->ether_clk);
@ -1215,8 +1216,10 @@ static int at91ether_resume(struct platform_device *pdev)
netif_device_attach(net_dev);
netif_start_queue(net_dev);
if (phy_irq)
if (gpio_is_valid(lp->board_data.phy_irq_pin)) {
int phy_irq = lp->board_data.phy_irq_pin;
enable_irq(phy_irq);
}
}
return 0;
}

View file

@ -1,5 +1,5 @@
/*
* Atmel MACB Ethernet Controller driver
* Cadence MACB/GEM Ethernet Controller driver
*
* Copyright (C) 2004-2006 Atmel Corporation
*
@ -23,6 +23,9 @@
#include <linux/platform_data/macb.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_net.h>
#include "macb.h"
@ -59,9 +62,9 @@ static void __macb_set_hwaddr(struct macb *bp)
u16 top;
bottom = cpu_to_le32(*((u32 *)bp->dev->dev_addr));
macb_writel(bp, SA1B, bottom);
macb_or_gem_writel(bp, SA1B, bottom);
top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4)));
macb_writel(bp, SA1T, top);
macb_or_gem_writel(bp, SA1T, top);
}
static void __init macb_get_hwaddr(struct macb *bp)
@ -70,8 +73,8 @@ static void __init macb_get_hwaddr(struct macb *bp)
u16 top;
u8 addr[6];
bottom = macb_readl(bp, SA1B);
top = macb_readl(bp, SA1T);
bottom = macb_or_gem_readl(bp, SA1B);
top = macb_or_gem_readl(bp, SA1T);
addr[0] = bottom & 0xff;
addr[1] = (bottom >> 8) & 0xff;
@ -191,7 +194,6 @@ static int macb_mii_probe(struct net_device *dev)
{
struct macb *bp = netdev_priv(dev);
struct phy_device *phydev;
struct macb_platform_data *pdata;
int ret;
phydev = phy_find_first(bp->mii_bus);
@ -200,14 +202,11 @@ static int macb_mii_probe(struct net_device *dev)
return -1;
}
pdata = bp->pdev->dev.platform_data;
/* TODO : add pin_irq */
/* attach the mac to the phy */
ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 0,
pdata && pdata->is_rmii ?
PHY_INTERFACE_MODE_RMII :
PHY_INTERFACE_MODE_MII);
bp->phy_interface);
if (ret) {
netdev_err(dev, "Could not attach to PHY\n");
return ret;
@ -285,8 +284,8 @@ err_out:
static void macb_update_stats(struct macb *bp)
{
u32 __iomem *reg = bp->regs + MACB_PFR;
u32 *p = &bp->hw_stats.rx_pause_frames;
u32 *end = &bp->hw_stats.tx_pause_frames + 1;
u32 *p = &bp->hw_stats.macb.rx_pause_frames;
u32 *end = &bp->hw_stats.macb.tx_pause_frames + 1;
WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4);
@ -580,7 +579,10 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
if (status & MACB_BIT(ISR_ROVR)) {
/* We missed at least one packet */
bp->hw_stats.rx_overruns++;
if (macb_is_gem(bp))
bp->hw_stats.gem.rx_overruns++;
else
bp->hw_stats.macb.rx_overruns++;
}
if (status & MACB_BIT(HRESP)) {
@ -790,6 +792,84 @@ static void macb_reset_hw(struct macb *bp)
macb_readl(bp, ISR);
}
static u32 gem_mdc_clk_div(struct macb *bp)
{
u32 config;
unsigned long pclk_hz = clk_get_rate(bp->pclk);
if (pclk_hz <= 20000000)
config = GEM_BF(CLK, GEM_CLK_DIV8);
else if (pclk_hz <= 40000000)
config = GEM_BF(CLK, GEM_CLK_DIV16);
else if (pclk_hz <= 80000000)
config = GEM_BF(CLK, GEM_CLK_DIV32);
else if (pclk_hz <= 120000000)
config = GEM_BF(CLK, GEM_CLK_DIV48);
else if (pclk_hz <= 160000000)
config = GEM_BF(CLK, GEM_CLK_DIV64);
else
config = GEM_BF(CLK, GEM_CLK_DIV96);
return config;
}
static u32 macb_mdc_clk_div(struct macb *bp)
{
u32 config;
unsigned long pclk_hz;
if (macb_is_gem(bp))
return gem_mdc_clk_div(bp);
pclk_hz = clk_get_rate(bp->pclk);
if (pclk_hz <= 20000000)
config = MACB_BF(CLK, MACB_CLK_DIV8);
else if (pclk_hz <= 40000000)
config = MACB_BF(CLK, MACB_CLK_DIV16);
else if (pclk_hz <= 80000000)
config = MACB_BF(CLK, MACB_CLK_DIV32);
else
config = MACB_BF(CLK, MACB_CLK_DIV64);
return config;
}
/*
* Get the DMA bus width field of the network configuration register that we
* should program. We find the width from decoding the design configuration
* register to find the maximum supported data bus width.
*/
static u32 macb_dbw(struct macb *bp)
{
if (!macb_is_gem(bp))
return 0;
switch (GEM_BFEXT(DBWDEF, gem_readl(bp, DCFG1))) {
case 4:
return GEM_BF(DBW, GEM_DBW128);
case 2:
return GEM_BF(DBW, GEM_DBW64);
case 1:
default:
return GEM_BF(DBW, GEM_DBW32);
}
}
/*
* Configure the receive DMA engine to use the correct receive buffer size.
* This is a configurable parameter for GEM.
*/
static void macb_configure_dma(struct macb *bp)
{
u32 dmacfg;
if (macb_is_gem(bp)) {
dmacfg = gem_readl(bp, DMACFG) & ~GEM_BF(RXBS, -1L);
dmacfg |= GEM_BF(RXBS, RX_BUFFER_SIZE / 64);
gem_writel(bp, DMACFG, dmacfg);
}
}
static void macb_init_hw(struct macb *bp)
{
u32 config;
@ -797,7 +877,7 @@ static void macb_init_hw(struct macb *bp)
macb_reset_hw(bp);
__macb_set_hwaddr(bp);
config = macb_readl(bp, NCFGR) & MACB_BF(CLK, -1L);
config = macb_mdc_clk_div(bp);
config |= MACB_BIT(PAE); /* PAuse Enable */
config |= MACB_BIT(DRFCS); /* Discard Rx FCS */
config |= MACB_BIT(BIG); /* Receive oversized frames */
@ -805,8 +885,11 @@ static void macb_init_hw(struct macb *bp)
config |= MACB_BIT(CAF); /* Copy All Frames */
if (!(bp->dev->flags & IFF_BROADCAST))
config |= MACB_BIT(NBC); /* No BroadCast */
config |= macb_dbw(bp);
macb_writel(bp, NCFGR, config);
macb_configure_dma(bp);
/* Initialize TX and RX buffers */
macb_writel(bp, RBQP, bp->rx_ring_dma);
macb_writel(bp, TBQP, bp->tx_ring_dma);
@ -902,8 +985,8 @@ static void macb_sethashtable(struct net_device *dev)
mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
}
macb_writel(bp, HRB, mc_filter[0]);
macb_writel(bp, HRT, mc_filter[1]);
macb_or_gem_writel(bp, HRB, mc_filter[0]);
macb_or_gem_writel(bp, HRT, mc_filter[1]);
}
/*
@ -925,8 +1008,8 @@ static void macb_set_rx_mode(struct net_device *dev)
if (dev->flags & IFF_ALLMULTI) {
/* Enable all multicast mode */
macb_writel(bp, HRB, -1);
macb_writel(bp, HRT, -1);
macb_or_gem_writel(bp, HRB, -1);
macb_or_gem_writel(bp, HRT, -1);
cfg |= MACB_BIT(NCFGR_MTI);
} else if (!netdev_mc_empty(dev)) {
/* Enable specific multicasts */
@ -934,8 +1017,8 @@ static void macb_set_rx_mode(struct net_device *dev)
cfg |= MACB_BIT(NCFGR_MTI);
} else if (dev->flags & (~IFF_ALLMULTI)) {
/* Disable all multicast mode */
macb_writel(bp, HRB, 0);
macb_writel(bp, HRT, 0);
macb_or_gem_writel(bp, HRB, 0);
macb_or_gem_writel(bp, HRT, 0);
cfg &= ~MACB_BIT(NCFGR_MTI);
}
@ -997,11 +1080,62 @@ static int macb_close(struct net_device *dev)
return 0;
}
static void gem_update_stats(struct macb *bp)
{
u32 __iomem *reg = bp->regs + GEM_OTX;
u32 *p = &bp->hw_stats.gem.tx_octets_31_0;
u32 *end = &bp->hw_stats.gem.rx_udp_checksum_errors + 1;
for (; p < end; p++, reg++)
*p += __raw_readl(reg);
}
static struct net_device_stats *gem_get_stats(struct macb *bp)
{
struct gem_stats *hwstat = &bp->hw_stats.gem;
struct net_device_stats *nstat = &bp->stats;
gem_update_stats(bp);
nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors +
hwstat->rx_alignment_errors +
hwstat->rx_resource_errors +
hwstat->rx_overruns +
hwstat->rx_oversize_frames +
hwstat->rx_jabbers +
hwstat->rx_undersized_frames +
hwstat->rx_length_field_frame_errors);
nstat->tx_errors = (hwstat->tx_late_collisions +
hwstat->tx_excessive_collisions +
hwstat->tx_underrun +
hwstat->tx_carrier_sense_errors);
nstat->multicast = hwstat->rx_multicast_frames;
nstat->collisions = (hwstat->tx_single_collision_frames +
hwstat->tx_multiple_collision_frames +
hwstat->tx_excessive_collisions);
nstat->rx_length_errors = (hwstat->rx_oversize_frames +
hwstat->rx_jabbers +
hwstat->rx_undersized_frames +
hwstat->rx_length_field_frame_errors);
nstat->rx_over_errors = hwstat->rx_resource_errors;
nstat->rx_crc_errors = hwstat->rx_frame_check_sequence_errors;
nstat->rx_frame_errors = hwstat->rx_alignment_errors;
nstat->rx_fifo_errors = hwstat->rx_overruns;
nstat->tx_aborted_errors = hwstat->tx_excessive_collisions;
nstat->tx_carrier_errors = hwstat->tx_carrier_sense_errors;
nstat->tx_fifo_errors = hwstat->tx_underrun;
return nstat;
}
static struct net_device_stats *macb_get_stats(struct net_device *dev)
{
struct macb *bp = netdev_priv(dev);
struct net_device_stats *nstat = &bp->stats;
struct macb_stats *hwstat = &bp->hw_stats;
struct macb_stats *hwstat = &bp->hw_stats.macb;
if (macb_is_gem(bp))
return gem_get_stats(bp);
/* read stats from hardware */
macb_update_stats(bp);
@ -1109,6 +1243,52 @@ static const struct net_device_ops macb_netdev_ops = {
#endif
};
#if defined(CONFIG_OF)
static const struct of_device_id macb_dt_ids[] = {
{ .compatible = "cdns,at32ap7000-macb" },
{ .compatible = "cdns,at91sam9260-macb" },
{ .compatible = "cdns,macb" },
{ .compatible = "cdns,pc302-gem" },
{ .compatible = "cdns,gem" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, macb_dt_ids);
static int __devinit macb_get_phy_mode_dt(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
if (np)
return of_get_phy_mode(np);
return -ENODEV;
}
static int __devinit macb_get_hwaddr_dt(struct macb *bp)
{
struct device_node *np = bp->pdev->dev.of_node;
if (np) {
const char *mac = of_get_mac_address(np);
if (mac) {
memcpy(bp->dev->dev_addr, mac, ETH_ALEN);
return 0;
}
}
return -ENODEV;
}
#else
static int __devinit macb_get_phy_mode_dt(struct platform_device *pdev)
{
return -ENODEV;
}
static int __devinit macb_get_hwaddr_dt(struct macb *bp)
{
return -ENODEV;
}
#endif
static int __init macb_probe(struct platform_device *pdev)
{
struct macb_platform_data *pdata;
@ -1116,7 +1296,6 @@ static int __init macb_probe(struct platform_device *pdev)
struct net_device *dev;
struct macb *bp;
struct phy_device *phydev;
unsigned long pclk_hz;
u32 config;
int err = -ENXIO;
@ -1180,31 +1359,37 @@ static int __init macb_probe(struct platform_device *pdev)
dev->base_addr = regs->start;
/* Set MII management clock divider */
pclk_hz = clk_get_rate(bp->pclk);
if (pclk_hz <= 20000000)
config = MACB_BF(CLK, MACB_CLK_DIV8);
else if (pclk_hz <= 40000000)
config = MACB_BF(CLK, MACB_CLK_DIV16);
else if (pclk_hz <= 80000000)
config = MACB_BF(CLK, MACB_CLK_DIV32);
else
config = MACB_BF(CLK, MACB_CLK_DIV64);
config = macb_mdc_clk_div(bp);
config |= macb_dbw(bp);
macb_writel(bp, NCFGR, config);
macb_get_hwaddr(bp);
pdata = pdev->dev.platform_data;
err = macb_get_hwaddr_dt(bp);
if (err < 0)
macb_get_hwaddr(bp);
if (pdata && pdata->is_rmii)
err = macb_get_phy_mode_dt(pdev);
if (err < 0) {
pdata = pdev->dev.platform_data;
if (pdata && pdata->is_rmii)
bp->phy_interface = PHY_INTERFACE_MODE_RMII;
else
bp->phy_interface = PHY_INTERFACE_MODE_MII;
} else {
bp->phy_interface = err;
}
if (bp->phy_interface == PHY_INTERFACE_MODE_RMII)
#if defined(CONFIG_ARCH_AT91)
macb_writel(bp, USRIO, (MACB_BIT(RMII) | MACB_BIT(CLKEN)) );
macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) |
MACB_BIT(CLKEN)));
#else
macb_writel(bp, USRIO, 0);
macb_or_gem_writel(bp, USRIO, 0);
#endif
else
#if defined(CONFIG_ARCH_AT91)
macb_writel(bp, USRIO, MACB_BIT(CLKEN));
macb_or_gem_writel(bp, USRIO, MACB_BIT(CLKEN));
#else
macb_writel(bp, USRIO, MACB_BIT(MII));
macb_or_gem_writel(bp, USRIO, MACB_BIT(MII));
#endif
bp->tx_pending = DEF_TX_RING_PENDING;
@ -1221,8 +1406,9 @@ static int __init macb_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev);
netdev_info(dev, "Atmel MACB at 0x%08lx irq %d (%pM)\n",
dev->base_addr, dev->irq, dev->dev_addr);
netdev_info(dev, "Cadence %s at 0x%08lx irq %d (%pM)\n",
macb_is_gem(bp) ? "GEM" : "MACB", dev->base_addr,
dev->irq, dev->dev_addr);
phydev = bp->phy_dev;
netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
@ -1315,6 +1501,7 @@ static struct platform_driver macb_driver = {
.driver = {
.name = "macb",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(macb_dt_ids),
},
};
@ -1332,6 +1519,6 @@ module_init(macb_init);
module_exit(macb_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Atmel MACB Ethernet driver");
MODULE_DESCRIPTION("Cadence MACB/GEM Ethernet driver");
MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
MODULE_ALIAS("platform:macb");

View file

@ -59,6 +59,24 @@
#define MACB_TPQ 0x00bc
#define MACB_USRIO 0x00c0
#define MACB_WOL 0x00c4
#define MACB_MID 0x00fc
/* GEM register offsets. */
#define GEM_NCFGR 0x0004
#define GEM_USRIO 0x000c
#define GEM_DMACFG 0x0010
#define GEM_HRB 0x0080
#define GEM_HRT 0x0084
#define GEM_SA1B 0x0088
#define GEM_SA1T 0x008C
#define GEM_OTX 0x0100
#define GEM_DCFG1 0x0280
#define GEM_DCFG2 0x0284
#define GEM_DCFG3 0x0288
#define GEM_DCFG4 0x028c
#define GEM_DCFG5 0x0290
#define GEM_DCFG6 0x0294
#define GEM_DCFG7 0x0298
/* Bitfields in NCR */
#define MACB_LB_OFFSET 0
@ -126,6 +144,21 @@
#define MACB_IRXFCS_OFFSET 19
#define MACB_IRXFCS_SIZE 1
/* GEM specific NCFGR bitfields. */
#define GEM_CLK_OFFSET 18
#define GEM_CLK_SIZE 3
#define GEM_DBW_OFFSET 21
#define GEM_DBW_SIZE 2
/* Constants for data bus width. */
#define GEM_DBW32 0
#define GEM_DBW64 1
#define GEM_DBW128 2
/* Bitfields in DMACFG. */
#define GEM_RXBS_OFFSET 16
#define GEM_RXBS_SIZE 8
/* Bitfields in NSR */
#define MACB_NSR_LINK_OFFSET 0
#define MACB_NSR_LINK_SIZE 1
@ -228,12 +261,30 @@
#define MACB_WOL_MTI_OFFSET 19
#define MACB_WOL_MTI_SIZE 1
/* Bitfields in MID */
#define MACB_IDNUM_OFFSET 16
#define MACB_IDNUM_SIZE 16
#define MACB_REV_OFFSET 0
#define MACB_REV_SIZE 16
/* Bitfields in DCFG1. */
#define GEM_DBWDEF_OFFSET 25
#define GEM_DBWDEF_SIZE 3
/* Constants for CLK */
#define MACB_CLK_DIV8 0
#define MACB_CLK_DIV16 1
#define MACB_CLK_DIV32 2
#define MACB_CLK_DIV64 3
/* GEM specific constants for CLK. */
#define GEM_CLK_DIV8 0
#define GEM_CLK_DIV16 1
#define GEM_CLK_DIV32 2
#define GEM_CLK_DIV48 3
#define GEM_CLK_DIV64 4
#define GEM_CLK_DIV96 5
/* Constants for MAN register */
#define MACB_MAN_SOF 1
#define MACB_MAN_WRITE 1
@ -254,11 +305,52 @@
<< MACB_##name##_OFFSET)) \
| MACB_BF(name,value))
#define GEM_BIT(name) \
(1 << GEM_##name##_OFFSET)
#define GEM_BF(name, value) \
(((value) & ((1 << GEM_##name##_SIZE) - 1)) \
<< GEM_##name##_OFFSET)
#define GEM_BFEXT(name, value)\
(((value) >> GEM_##name##_OFFSET) \
& ((1 << GEM_##name##_SIZE) - 1))
#define GEM_BFINS(name, value, old) \
(((old) & ~(((1 << GEM_##name##_SIZE) - 1) \
<< GEM_##name##_OFFSET)) \
| GEM_BF(name, value))
/* Register access macros */
#define macb_readl(port,reg) \
__raw_readl((port)->regs + MACB_##reg)
#define macb_writel(port,reg,value) \
__raw_writel((value), (port)->regs + MACB_##reg)
#define gem_readl(port, reg) \
__raw_readl((port)->regs + GEM_##reg)
#define gem_writel(port, reg, value) \
__raw_writel((value), (port)->regs + GEM_##reg)
/*
* Conditional GEM/MACB macros. These perform the operation to the correct
* register dependent on whether the device is a GEM or a MACB. For registers
* and bitfields that are common across both devices, use macb_{read,write}l
* to avoid the cost of the conditional.
*/
#define macb_or_gem_writel(__bp, __reg, __value) \
({ \
if (macb_is_gem((__bp))) \
gem_writel((__bp), __reg, __value); \
else \
macb_writel((__bp), __reg, __value); \
})
#define macb_or_gem_readl(__bp, __reg) \
({ \
u32 __v; \
if (macb_is_gem((__bp))) \
__v = gem_readl((__bp), __reg); \
else \
__v = macb_readl((__bp), __reg); \
__v; \
})
struct dma_desc {
u32 addr;
@ -358,6 +450,54 @@ struct macb_stats {
u32 tx_pause_frames;
};
struct gem_stats {
u32 tx_octets_31_0;
u32 tx_octets_47_32;
u32 tx_frames;
u32 tx_broadcast_frames;
u32 tx_multicast_frames;
u32 tx_pause_frames;
u32 tx_64_byte_frames;
u32 tx_65_127_byte_frames;
u32 tx_128_255_byte_frames;
u32 tx_256_511_byte_frames;
u32 tx_512_1023_byte_frames;
u32 tx_1024_1518_byte_frames;
u32 tx_greater_than_1518_byte_frames;
u32 tx_underrun;
u32 tx_single_collision_frames;
u32 tx_multiple_collision_frames;
u32 tx_excessive_collisions;
u32 tx_late_collisions;
u32 tx_deferred_frames;
u32 tx_carrier_sense_errors;
u32 rx_octets_31_0;
u32 rx_octets_47_32;
u32 rx_frames;
u32 rx_broadcast_frames;
u32 rx_multicast_frames;
u32 rx_pause_frames;
u32 rx_64_byte_frames;
u32 rx_65_127_byte_frames;
u32 rx_128_255_byte_frames;
u32 rx_256_511_byte_frames;
u32 rx_512_1023_byte_frames;
u32 rx_1024_1518_byte_frames;
u32 rx_greater_than_1518_byte_frames;
u32 rx_undersized_frames;
u32 rx_oversize_frames;
u32 rx_jabbers;
u32 rx_frame_check_sequence_errors;
u32 rx_length_field_frame_errors;
u32 rx_symbol_errors;
u32 rx_alignment_errors;
u32 rx_resource_errors;
u32 rx_overruns;
u32 rx_ip_header_checksum_errors;
u32 rx_tcp_checksum_errors;
u32 rx_udp_checksum_errors;
};
struct macb {
void __iomem *regs;
@ -376,7 +516,10 @@ struct macb {
struct net_device *dev;
struct napi_struct napi;
struct net_device_stats stats;
struct macb_stats hw_stats;
union {
struct macb_stats macb;
struct gem_stats gem;
} hw_stats;
dma_addr_t rx_ring_dma;
dma_addr_t tx_ring_dma;
@ -389,6 +532,13 @@ struct macb {
unsigned int link;
unsigned int speed;
unsigned int duplex;
phy_interface_t phy_interface;
};
static inline bool macb_is_gem(struct macb *bp)
{
return MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2;
}
#endif /* _MACB_H */