mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
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:
commit
2ac9d7aacc
169 changed files with 3010 additions and 1631 deletions
|
|
@ -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/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in a new issue