* [PATCH 1/3] NET: MIPS: lantiq: make etop ethernet work on ase/ar9
@ 2011-11-17 16:42 John Crispin
2011-11-17 16:42 ` [PATCH 2/3] NET: MIPS: lantiq: non existing phy was not handled gracefully John Crispin
2011-11-17 16:42 ` [PATCH 3/3] NET: MIPS: lantiq: return value of request_irq " John Crispin
0 siblings, 2 replies; 5+ messages in thread
From: John Crispin @ 2011-11-17 16:42 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips, John Crispin
Extend the driver to handle the different DMA channel layout for AR9 and
Amazon-SE SoCs. The patch also adds support for the integrated PHY found
on Amazon-SE and the gigabit switch found inside the AR9.
Signed-off-by: John Crispin <blogic@openwrt.org>
Acked-by: David S. Miller <davem@davemloft.net>
---
.../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 22 +---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 10 ++
arch/mips/lantiq/xway/devices.c | 11 +-
arch/mips/lantiq/xway/mach-easy50601.c | 5 +
drivers/net/ethernet/lantiq_etop.c | 171 ++++++++++++++++++--
5 files changed, 179 insertions(+), 40 deletions(-)
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
index b4465a8..2a8d5ad 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
@@ -38,26 +38,8 @@
#define MIPS_CPU_TIMER_IRQ 7
-#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0)
-#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1)
-#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2)
-#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3)
-#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4)
-#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5)
-#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6)
-#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7)
-#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8)
-#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9)
-#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10)
-#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11)
-#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25)
-#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26)
-#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27)
-#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28)
-#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29)
-#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30)
-#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16)
-#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21)
+#define LTQ_DMA_ETOP ((ltq_is_ase()) ? \
+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
#define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
index e31f52d..6983d75 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -82,6 +82,7 @@
#define LTQ_PMU_SIZE 0x1000
#define PMU_DMA 0x0020
+#define PMU_EPHY 0x0080
#define PMU_USB 0x8041
#define PMU_LED 0x0800
#define PMU_GPT 0x1000
@@ -93,6 +94,10 @@
#define LTQ_ETOP_BASE_ADDR 0x1E180000
#define LTQ_ETOP_SIZE 0x40000
+/* GBIT - gigabit switch */
+#define LTQ_GBIT_BASE_ADDR 0x1E108000
+#define LTQ_GBIT_SIZE 0x200
+
/* DMA */
#define LTQ_DMA_BASE_ADDR 0x1E104100
#define LTQ_DMA_SIZE 0x800
@@ -147,6 +152,11 @@ extern void ltq_pmu_enable(unsigned int module);
extern void ltq_pmu_disable(unsigned int module);
extern void ltq_cgu_enable(unsigned int clk);
+static inline int ltq_is_ase(void)
+{
+ return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE);
+}
+
static inline int ltq_is_ar9(void)
{
return (ltq_get_soc_type() == SOC_TYPE_AR9);
diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
index f97e565..eab4644d 100644
--- a/arch/mips/lantiq/xway/devices.c
+++ b/arch/mips/lantiq/xway/devices.c
@@ -74,18 +74,23 @@ void __init ltq_register_ase_asc(void)
}
/* ethernet */
-static struct resource ltq_etop_resources =
- MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE);
+static struct resource ltq_etop_resources[] = {
+ MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE),
+ MEM_RES("gbit", LTQ_GBIT_BASE_ADDR, LTQ_GBIT_SIZE),
+};
static struct platform_device ltq_etop = {
.name = "ltq_etop",
- .resource = <q_etop_resources,
+ .resource = ltq_etop_resources,
.num_resources = 1,
};
void __init
ltq_register_etop(struct ltq_eth_data *eth)
{
+ /* only register the gphy on socs that have one */
+ if (ltq_is_ar9() | ltq_is_vr9())
+ ltq_etop.num_resources = 2;
if (eth) {
ltq_etop.dev.platform_data = eth;
platform_device_register(<q_etop);
diff --git a/arch/mips/lantiq/xway/mach-easy50601.c b/arch/mips/lantiq/xway/mach-easy50601.c
index d5aaf63..16d65e0 100644
--- a/arch/mips/lantiq/xway/mach-easy50601.c
+++ b/arch/mips/lantiq/xway/mach-easy50601.c
@@ -46,9 +46,14 @@ static struct physmap_flash_data easy50601_flash_data = {
.parts = easy50601_partitions,
};
+static struct ltq_eth_data ltq_eth_data = {
+ .mii_mode = -1, /* use EPHY */
+};
+
static void __init easy50601_init(void)
{
ltq_register_nor(&easy50601_flash_data);
+ ltq_register_etop(<q_eth_data);
}
MIPS_MACHINE(LTQ_MACH_EASY50601,
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
index 0b3567a..d3d4931 100644
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -71,10 +71,43 @@
#define ETOP_MII_REVERSE 0xe
#define ETOP_PLEN_UNDER 0x40
#define ETOP_CGEN 0x800
-
-/* use 2 static channels for TX/RX */
+#define ETOP_CFG_MII0 0x01
+
+#define LTQ_GBIT_MDIO_CTL 0xCC
+#define LTQ_GBIT_MDIO_DATA 0xd0
+#define LTQ_GBIT_GCTL0 0x68
+#define LTQ_GBIT_PMAC_HD_CTL 0x8c
+#define LTQ_GBIT_P0_CTL 0x4
+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
+
+#define PMAC_HD_CTL_AS (1 << 19)
+#define PMAC_HD_CTL_RXSH (1 << 22)
+
+/* Switch Enable (0=disable, 1=enable) */
+#define GCTL0_SE 0x80000000
+/* Disable MDIO auto polling (0=disable, 1=enable) */
+#define PX_CTL_DMDIO 0x00400000
+
+/* register information for the gbit's MDIO bus */
+#define MDIO_XR9_REQUEST 0x00008000
+#define MDIO_XR9_READ 0x00000800
+#define MDIO_XR9_WRITE 0x00000400
+#define MDIO_XR9_REG_MASK 0x1f
+#define MDIO_XR9_ADDR_MASK 0x1f
+#define MDIO_XR9_RD_MASK 0xffff
+#define MDIO_XR9_REG_OFFSET 0
+#define MDIO_XR9_ADDR_OFFSET 5
+#define MDIO_XR9_WR_OFFSET 16
+
+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
+#define ltq_has_gbit() (ltq_is_ar9() || ltq_is_vr9())
+
+/* use 2 static channels for TX/RX
+ depending on the SoC we need to use different DMA channels for ethernet */
#define LTQ_ETOP_TX_CHANNEL 1
-#define LTQ_ETOP_RX_CHANNEL 6
+#define LTQ_ETOP_RX_CHANNEL ((ltq_is_ase()) ? (5) : \
+ ((ltq_has_gbit()) ? (0) : (6)))
+
#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
@@ -83,9 +116,15 @@
#define ltq_etop_w32_mask(x, y, z) \
ltq_w32_mask(x, y, ltq_etop_membase + (z))
+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x))
+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y))
+#define ltq_gbit_w32_mask(x, y, z) \
+ ltq_w32_mask(x, y, ltq_gbit_membase + (z))
+
#define DRV_VERSION "1.0"
static void __iomem *ltq_etop_membase;
+static void __iomem *ltq_gbit_membase;
struct ltq_etop_chan {
int idx;
@@ -110,6 +149,9 @@ struct ltq_etop_priv {
spinlock_t lock;
};
+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
+ int phy_reg, u16 phy_data);
+
static int
ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
{
@@ -211,7 +253,7 @@ static irqreturn_t
ltq_etop_dma_irq(int irq, void *_priv)
{
struct ltq_etop_priv *priv = _priv;
- int ch = irq - LTQ_DMA_CH0_INT;
+ int ch = irq - LTQ_DMA_ETOP;
napi_schedule(&priv->ch[ch].napi);
return IRQ_HANDLED;
@@ -244,15 +286,43 @@ ltq_etop_hw_exit(struct net_device *dev)
ltq_etop_free_channel(dev, &priv->ch[i]);
}
+static void
+ltq_etop_gbit_init(void)
+{
+ ltq_pmu_enable(PMU_SWITCH);
+
+ ltq_gpio_request(42, 2, 1, "MDIO");
+ ltq_gpio_request(43, 2, 1, "MDC");
+
+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
+ /** Disable MDIO auto polling mode */
+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
+ /* set 1522 packet size */
+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
+ /* disable pmac & dmac headers */
+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
+ LTQ_GBIT_PMAC_HD_CTL);
+ /* Due to traffic halt when burst length 8,
+ replace default IPG value with 0x3B */
+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
+}
+
static int
ltq_etop_hw_init(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
+ unsigned int mii_mode = priv->pldata->mii_mode;
int i;
ltq_pmu_enable(PMU_PPE);
- switch (priv->pldata->mii_mode) {
+ if (ltq_has_gbit()) {
+ ltq_etop_gbit_init();
+ /* force the etops link to the gbit to MII */
+ mii_mode = PHY_INTERFACE_MODE_MII;
+ }
+
+ switch (mii_mode) {
case PHY_INTERFACE_MODE_RMII:
ltq_etop_w32_mask(ETOP_MII_MASK,
ETOP_MII_REVERSE, LTQ_ETOP_CFG);
@@ -264,6 +334,18 @@ ltq_etop_hw_init(struct net_device *dev)
break;
default:
+ if (ltq_is_ase()) {
+ ltq_pmu_enable(PMU_EPHY);
+ /* disable external MII */
+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
+ /* enable clock for internal PHY */
+ ltq_cgu_enable(CGU_EPHY);
+ /* we need to write this magic to the internal phy to
+ make it work */
+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
+ pr_info("Selected EPHY mode\n");
+ break;
+ }
netdev_err(dev, "unknown mii mode %d\n",
priv->pldata->mii_mode);
return -ENOTSUPP;
@@ -275,7 +357,7 @@ ltq_etop_hw_init(struct net_device *dev)
ltq_dma_init_port(DMA_PORT_ETOP);
for (i = 0; i < MAX_DMA_CHAN; i++) {
- int irq = LTQ_DMA_CH0_INT + i;
+ int irq = LTQ_DMA_ETOP + i;
struct ltq_etop_chan *ch = &priv->ch[i];
ch->idx = ch->dma.nr = i;
@@ -339,6 +421,39 @@ static const struct ethtool_ops ltq_etop_ethtool_ops = {
};
static int
+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
+ int phy_reg, u16 phy_data)
+{
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
+ (phy_data << MDIO_XR9_WR_OFFSET) |
+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
+
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ return 0;
+}
+
+static int
+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg)
+{
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ |
+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
+
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK;
+ return val;
+}
+
+static int
ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
{
u32 val = MDIO_REQUEST |
@@ -379,14 +494,11 @@ ltq_etop_mdio_probe(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
struct phy_device *phydev = NULL;
- int phy_addr;
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
- if (priv->mii_bus->phy_map[phy_addr]) {
- phydev = priv->mii_bus->phy_map[phy_addr];
- break;
- }
- }
+ if (ltq_is_ase())
+ phydev = priv->mii_bus->phy_map[8];
+ else
+ phydev = priv->mii_bus->phy_map[0];
if (!phydev) {
netdev_err(dev, "no PHY found\n");
@@ -408,6 +520,9 @@ ltq_etop_mdio_probe(struct net_device *dev)
| SUPPORTED_Autoneg
| SUPPORTED_MII
| SUPPORTED_TP);
+ if (ltq_has_gbit())
+ phydev->supported &= SUPPORTED_1000baseT_Half
+ | SUPPORTED_1000baseT_Full;
phydev->advertising = phydev->supported;
priv->phydev = phydev;
@@ -433,8 +548,13 @@ ltq_etop_mdio_init(struct net_device *dev)
}
priv->mii_bus->priv = dev;
- priv->mii_bus->read = ltq_etop_mdio_rd;
- priv->mii_bus->write = ltq_etop_mdio_wr;
+ if (ltq_has_gbit()) {
+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9;
+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9;
+ } else {
+ priv->mii_bus->read = ltq_etop_mdio_rd;
+ priv->mii_bus->write = ltq_etop_mdio_wr;
+ }
priv->mii_bus->name = "ltq_mii";
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
@@ -524,9 +644,9 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
struct ltq_etop_priv *priv = netdev_priv(dev);
struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
- int len;
unsigned long flags;
u32 byte_offset;
+ int len;
len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
@@ -700,7 +820,7 @@ ltq_etop_probe(struct platform_device *pdev)
{
struct net_device *dev;
struct ltq_etop_priv *priv;
- struct resource *res;
+ struct resource *res, *gbit_res;
int err;
int i;
@@ -728,6 +848,23 @@ ltq_etop_probe(struct platform_device *pdev)
goto err_out;
}
+ if (ltq_has_gbit()) {
+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!gbit_res) {
+ dev_err(&pdev->dev, "failed to get gbit resource\n");
+ err = -ENOENT;
+ goto err_out;
+ }
+ ltq_gbit_membase = devm_ioremap_nocache(&pdev->dev,
+ gbit_res->start, resource_size(gbit_res));
+ if (!ltq_gbit_membase) {
+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
+ pdev->id);
+ err = -ENOMEM;
+ goto err_out;
+ }
+ }
+
dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
strcpy(dev->name, "eth%d");
dev->netdev_ops = <q_eth_netdev_ops;
--
1.7.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/3] NET: MIPS: lantiq: non existing phy was not handled gracefully
2011-11-17 16:42 [PATCH 1/3] NET: MIPS: lantiq: make etop ethernet work on ase/ar9 John Crispin
@ 2011-11-17 16:42 ` John Crispin
2011-11-17 16:42 ` [PATCH 3/3] NET: MIPS: lantiq: return value of request_irq " John Crispin
1 sibling, 0 replies; 5+ messages in thread
From: John Crispin @ 2011-11-17 16:42 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips, John Crispin
The code blindly assumed that that a PHY device was present causing a BadVA.
In addition the driver should not fail to load incase no PHY was found.
Instead we print the following line and continue with no attached PHY.
etop: mdio probe failed
Signed-off-by: John Crispin <blogic@openwrt.org>
Acked-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/lantiq_etop.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
index d3d4931..9fd6779 100644
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -612,7 +612,8 @@ ltq_etop_open(struct net_device *dev)
ltq_dma_open(&ch->dma);
napi_enable(&ch->napi);
}
- phy_start(priv->phydev);
+ if (priv->phydev)
+ phy_start(priv->phydev);
netif_tx_start_all_queues(dev);
return 0;
}
@@ -624,7 +625,8 @@ ltq_etop_stop(struct net_device *dev)
int i;
netif_tx_stop_all_queues(dev);
- phy_stop(priv->phydev);
+ if (priv->phydev)
+ phy_stop(priv->phydev);
for (i = 0; i < MAX_DMA_CHAN; i++) {
struct ltq_etop_chan *ch = &priv->ch[i];
@@ -770,9 +772,10 @@ ltq_etop_init(struct net_device *dev)
if (err)
goto err_netdev;
ltq_etop_set_multicast_list(dev);
- err = ltq_etop_mdio_init(dev);
- if (err)
- goto err_netdev;
+ if (!ltq_etop_mdio_init(dev))
+ dev->ethtool_ops = <q_etop_ethtool_ops;
+ else
+ pr_warn("etop: mdio probe failed\n");;
return 0;
err_netdev:
@@ -868,7 +871,6 @@ ltq_etop_probe(struct platform_device *pdev)
dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
strcpy(dev->name, "eth%d");
dev->netdev_ops = <q_eth_netdev_ops;
- dev->ethtool_ops = <q_etop_ethtool_ops;
priv = netdev_priv(dev);
priv->res = res;
priv->pldata = dev_get_platdata(&pdev->dev);
--
1.7.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 3/3] NET: MIPS: lantiq: return value of request_irq was not handled gracefully
2011-11-17 16:42 [PATCH 1/3] NET: MIPS: lantiq: make etop ethernet work on ase/ar9 John Crispin
2011-11-17 16:42 ` [PATCH 2/3] NET: MIPS: lantiq: non existing phy was not handled gracefully John Crispin
@ 2011-11-17 16:42 ` John Crispin
2011-11-18 8:52 ` Sergei Shtylyov
1 sibling, 1 reply; 5+ messages in thread
From: John Crispin @ 2011-11-17 16:42 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips, John Crispin
The return values of request_irq() were not checked leading to the following
error message.
drivers/net/ethernet/lantiq_etop.c: In function 'ltq_etop_hw_init':
drivers/net/ethernet/lantiq_etop.c:368:15: warning: ignoring return value of 'request_irq', declared with attribute warn_unused_result
drivers/net/ethernet/lantiq_etop.c:377:15: warning: ignoring return value of 'request_irq', declared with attribute warn_unused_result
Signed-off-by: John Crispin <blogic@openwrt.org>
Acked-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/lantiq_etop.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
index 9fd6779..dddb9fe 100644
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -312,6 +312,7 @@ ltq_etop_hw_init(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
unsigned int mii_mode = priv->pldata->mii_mode;
+ int err = 0;
int i;
ltq_pmu_enable(PMU_PPE);
@@ -356,7 +357,7 @@ ltq_etop_hw_init(struct net_device *dev)
ltq_dma_init_port(DMA_PORT_ETOP);
- for (i = 0; i < MAX_DMA_CHAN; i++) {
+ for (i = 0; i < MAX_DMA_CHAN && !err; i++) {
int irq = LTQ_DMA_ETOP + i;
struct ltq_etop_chan *ch = &priv->ch[i];
@@ -364,21 +365,22 @@ ltq_etop_hw_init(struct net_device *dev)
if (IS_TX(i)) {
ltq_dma_alloc_tx(&ch->dma);
- request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+ err = request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
"etop_tx", priv);
} else if (IS_RX(i)) {
ltq_dma_alloc_rx(&ch->dma);
for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
ch->dma.desc++)
if (ltq_etop_alloc_skb(ch))
- return -ENOMEM;
+ err = -ENOMEM;
ch->dma.desc = 0;
- request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+ err = request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
"etop_rx", priv);
}
- ch->dma.irq = irq;
+ if (!err)
+ ch->dma.irq = irq;
}
- return 0;
+ return err;
}
static void
--
1.7.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 3/3] NET: MIPS: lantiq: return value of request_irq was not handled gracefully
2011-11-17 16:42 ` [PATCH 3/3] NET: MIPS: lantiq: return value of request_irq " John Crispin
@ 2011-11-18 8:52 ` Sergei Shtylyov
0 siblings, 0 replies; 5+ messages in thread
From: Sergei Shtylyov @ 2011-11-18 8:52 UTC (permalink / raw)
To: John Crispin; +Cc: Ralf Baechle, linux-mips
Hello.
On 17-11-2011 20:42, John Crispin wrote:
> The return values of request_irq() were not checked leading to the following
> error message.
> drivers/net/ethernet/lantiq_etop.c: In function 'ltq_etop_hw_init':
> drivers/net/ethernet/lantiq_etop.c:368:15: warning: ignoring return value of 'request_irq', declared with attribute warn_unused_result
> drivers/net/ethernet/lantiq_etop.c:377:15: warning: ignoring return value of 'request_irq', declared with attribute warn_unused_result
> Signed-off-by: John Crispin<blogic@openwrt.org>
> Acked-by: David S. Miller<davem@davemloft.net>
> ---
> drivers/net/ethernet/lantiq_etop.c | 14 ++++++++------
> 1 files changed, 8 insertions(+), 6 deletions(-)
> diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
> index 9fd6779..dddb9fe 100644
> --- a/drivers/net/ethernet/lantiq_etop.c
> +++ b/drivers/net/ethernet/lantiq_etop.c
[...]
> @@ -364,21 +365,22 @@ ltq_etop_hw_init(struct net_device *dev)
>
> if (IS_TX(i)) {
> ltq_dma_alloc_tx(&ch->dma);
> - request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
> + err = request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
BTW, IRQF_DISABLED is a nop now, so could have dropped it...
> "etop_tx", priv);
> } else if (IS_RX(i)) {
> ltq_dma_alloc_rx(&ch->dma);
> for (ch->dma.desc = 0; ch->dma.desc< LTQ_DESC_NUM;
> ch->dma.desc++)
> if (ltq_etop_alloc_skb(ch))
> - return -ENOMEM;
> + err = -ENOMEM;
> ch->dma.desc = 0;
> - request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
> + err = request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
Same here.
WBR, Sergei
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] NET: MIPS: lantiq: make etop ethernet work on ase/ar9
@ 2011-11-16 14:41 John Crispin
2011-11-16 14:41 ` [PATCH 3/3] NET: MIPS: lantiq: return value of request_irq was not handled gracefully John Crispin
0 siblings, 1 reply; 5+ messages in thread
From: John Crispin @ 2011-11-16 14:41 UTC (permalink / raw)
To: netdev; +Cc: John Crispin
Extend the driver to handle the different DMA channel layout for AR9 and
Amazon-SE SoCs. The patch also adds support for the integrated PHY found
on Amazon-SE and the gigabit switch found inside the AR9.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: netdev@vger.kernel.org
---
.../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 22 +---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 10 ++
arch/mips/lantiq/xway/devices.c | 11 +-
arch/mips/lantiq/xway/mach-easy50601.c | 5 +
drivers/net/ethernet/lantiq_etop.c | 171 ++++++++++++++++++--
5 files changed, 179 insertions(+), 40 deletions(-)
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
index b4465a8..2a8d5ad 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
@@ -38,26 +38,8 @@
#define MIPS_CPU_TIMER_IRQ 7
-#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0)
-#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1)
-#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2)
-#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3)
-#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4)
-#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5)
-#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6)
-#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7)
-#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8)
-#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9)
-#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10)
-#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11)
-#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25)
-#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26)
-#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27)
-#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28)
-#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29)
-#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30)
-#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16)
-#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21)
+#define LTQ_DMA_ETOP ((ltq_is_ase()) ? \
+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
#define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
index e31f52d..6983d75 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -82,6 +82,7 @@
#define LTQ_PMU_SIZE 0x1000
#define PMU_DMA 0x0020
+#define PMU_EPHY 0x0080
#define PMU_USB 0x8041
#define PMU_LED 0x0800
#define PMU_GPT 0x1000
@@ -93,6 +94,10 @@
#define LTQ_ETOP_BASE_ADDR 0x1E180000
#define LTQ_ETOP_SIZE 0x40000
+/* GBIT - gigabit switch */
+#define LTQ_GBIT_BASE_ADDR 0x1E108000
+#define LTQ_GBIT_SIZE 0x200
+
/* DMA */
#define LTQ_DMA_BASE_ADDR 0x1E104100
#define LTQ_DMA_SIZE 0x800
@@ -147,6 +152,11 @@ extern void ltq_pmu_enable(unsigned int module);
extern void ltq_pmu_disable(unsigned int module);
extern void ltq_cgu_enable(unsigned int clk);
+static inline int ltq_is_ase(void)
+{
+ return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE);
+}
+
static inline int ltq_is_ar9(void)
{
return (ltq_get_soc_type() == SOC_TYPE_AR9);
diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
index f97e565..eab4644d 100644
--- a/arch/mips/lantiq/xway/devices.c
+++ b/arch/mips/lantiq/xway/devices.c
@@ -74,18 +74,23 @@ void __init ltq_register_ase_asc(void)
}
/* ethernet */
-static struct resource ltq_etop_resources =
- MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE);
+static struct resource ltq_etop_resources[] = {
+ MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE),
+ MEM_RES("gbit", LTQ_GBIT_BASE_ADDR, LTQ_GBIT_SIZE),
+};
static struct platform_device ltq_etop = {
.name = "ltq_etop",
- .resource = <q_etop_resources,
+ .resource = ltq_etop_resources,
.num_resources = 1,
};
void __init
ltq_register_etop(struct ltq_eth_data *eth)
{
+ /* only register the gphy on socs that have one */
+ if (ltq_is_ar9() | ltq_is_vr9())
+ ltq_etop.num_resources = 2;
if (eth) {
ltq_etop.dev.platform_data = eth;
platform_device_register(<q_etop);
diff --git a/arch/mips/lantiq/xway/mach-easy50601.c b/arch/mips/lantiq/xway/mach-easy50601.c
index d5aaf63..16d65e0 100644
--- a/arch/mips/lantiq/xway/mach-easy50601.c
+++ b/arch/mips/lantiq/xway/mach-easy50601.c
@@ -46,9 +46,14 @@ static struct physmap_flash_data easy50601_flash_data = {
.parts = easy50601_partitions,
};
+static struct ltq_eth_data ltq_eth_data = {
+ .mii_mode = -1, /* use EPHY */
+};
+
static void __init easy50601_init(void)
{
ltq_register_nor(&easy50601_flash_data);
+ ltq_register_etop(<q_eth_data);
}
MIPS_MACHINE(LTQ_MACH_EASY50601,
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
index 0b3567a..d3d4931 100644
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -71,10 +71,43 @@
#define ETOP_MII_REVERSE 0xe
#define ETOP_PLEN_UNDER 0x40
#define ETOP_CGEN 0x800
-
-/* use 2 static channels for TX/RX */
+#define ETOP_CFG_MII0 0x01
+
+#define LTQ_GBIT_MDIO_CTL 0xCC
+#define LTQ_GBIT_MDIO_DATA 0xd0
+#define LTQ_GBIT_GCTL0 0x68
+#define LTQ_GBIT_PMAC_HD_CTL 0x8c
+#define LTQ_GBIT_P0_CTL 0x4
+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
+
+#define PMAC_HD_CTL_AS (1 << 19)
+#define PMAC_HD_CTL_RXSH (1 << 22)
+
+/* Switch Enable (0=disable, 1=enable) */
+#define GCTL0_SE 0x80000000
+/* Disable MDIO auto polling (0=disable, 1=enable) */
+#define PX_CTL_DMDIO 0x00400000
+
+/* register information for the gbit's MDIO bus */
+#define MDIO_XR9_REQUEST 0x00008000
+#define MDIO_XR9_READ 0x00000800
+#define MDIO_XR9_WRITE 0x00000400
+#define MDIO_XR9_REG_MASK 0x1f
+#define MDIO_XR9_ADDR_MASK 0x1f
+#define MDIO_XR9_RD_MASK 0xffff
+#define MDIO_XR9_REG_OFFSET 0
+#define MDIO_XR9_ADDR_OFFSET 5
+#define MDIO_XR9_WR_OFFSET 16
+
+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
+#define ltq_has_gbit() (ltq_is_ar9() || ltq_is_vr9())
+
+/* use 2 static channels for TX/RX
+ depending on the SoC we need to use different DMA channels for ethernet */
#define LTQ_ETOP_TX_CHANNEL 1
-#define LTQ_ETOP_RX_CHANNEL 6
+#define LTQ_ETOP_RX_CHANNEL ((ltq_is_ase()) ? (5) : \
+ ((ltq_has_gbit()) ? (0) : (6)))
+
#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
@@ -83,9 +116,15 @@
#define ltq_etop_w32_mask(x, y, z) \
ltq_w32_mask(x, y, ltq_etop_membase + (z))
+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x))
+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y))
+#define ltq_gbit_w32_mask(x, y, z) \
+ ltq_w32_mask(x, y, ltq_gbit_membase + (z))
+
#define DRV_VERSION "1.0"
static void __iomem *ltq_etop_membase;
+static void __iomem *ltq_gbit_membase;
struct ltq_etop_chan {
int idx;
@@ -110,6 +149,9 @@ struct ltq_etop_priv {
spinlock_t lock;
};
+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
+ int phy_reg, u16 phy_data);
+
static int
ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
{
@@ -211,7 +253,7 @@ static irqreturn_t
ltq_etop_dma_irq(int irq, void *_priv)
{
struct ltq_etop_priv *priv = _priv;
- int ch = irq - LTQ_DMA_CH0_INT;
+ int ch = irq - LTQ_DMA_ETOP;
napi_schedule(&priv->ch[ch].napi);
return IRQ_HANDLED;
@@ -244,15 +286,43 @@ ltq_etop_hw_exit(struct net_device *dev)
ltq_etop_free_channel(dev, &priv->ch[i]);
}
+static void
+ltq_etop_gbit_init(void)
+{
+ ltq_pmu_enable(PMU_SWITCH);
+
+ ltq_gpio_request(42, 2, 1, "MDIO");
+ ltq_gpio_request(43, 2, 1, "MDC");
+
+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
+ /** Disable MDIO auto polling mode */
+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
+ /* set 1522 packet size */
+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
+ /* disable pmac & dmac headers */
+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
+ LTQ_GBIT_PMAC_HD_CTL);
+ /* Due to traffic halt when burst length 8,
+ replace default IPG value with 0x3B */
+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
+}
+
static int
ltq_etop_hw_init(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
+ unsigned int mii_mode = priv->pldata->mii_mode;
int i;
ltq_pmu_enable(PMU_PPE);
- switch (priv->pldata->mii_mode) {
+ if (ltq_has_gbit()) {
+ ltq_etop_gbit_init();
+ /* force the etops link to the gbit to MII */
+ mii_mode = PHY_INTERFACE_MODE_MII;
+ }
+
+ switch (mii_mode) {
case PHY_INTERFACE_MODE_RMII:
ltq_etop_w32_mask(ETOP_MII_MASK,
ETOP_MII_REVERSE, LTQ_ETOP_CFG);
@@ -264,6 +334,18 @@ ltq_etop_hw_init(struct net_device *dev)
break;
default:
+ if (ltq_is_ase()) {
+ ltq_pmu_enable(PMU_EPHY);
+ /* disable external MII */
+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
+ /* enable clock for internal PHY */
+ ltq_cgu_enable(CGU_EPHY);
+ /* we need to write this magic to the internal phy to
+ make it work */
+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
+ pr_info("Selected EPHY mode\n");
+ break;
+ }
netdev_err(dev, "unknown mii mode %d\n",
priv->pldata->mii_mode);
return -ENOTSUPP;
@@ -275,7 +357,7 @@ ltq_etop_hw_init(struct net_device *dev)
ltq_dma_init_port(DMA_PORT_ETOP);
for (i = 0; i < MAX_DMA_CHAN; i++) {
- int irq = LTQ_DMA_CH0_INT + i;
+ int irq = LTQ_DMA_ETOP + i;
struct ltq_etop_chan *ch = &priv->ch[i];
ch->idx = ch->dma.nr = i;
@@ -339,6 +421,39 @@ static const struct ethtool_ops ltq_etop_ethtool_ops = {
};
static int
+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
+ int phy_reg, u16 phy_data)
+{
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
+ (phy_data << MDIO_XR9_WR_OFFSET) |
+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
+
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ return 0;
+}
+
+static int
+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg)
+{
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ |
+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
+
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
+ ;
+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK;
+ return val;
+}
+
+static int
ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
{
u32 val = MDIO_REQUEST |
@@ -379,14 +494,11 @@ ltq_etop_mdio_probe(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
struct phy_device *phydev = NULL;
- int phy_addr;
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
- if (priv->mii_bus->phy_map[phy_addr]) {
- phydev = priv->mii_bus->phy_map[phy_addr];
- break;
- }
- }
+ if (ltq_is_ase())
+ phydev = priv->mii_bus->phy_map[8];
+ else
+ phydev = priv->mii_bus->phy_map[0];
if (!phydev) {
netdev_err(dev, "no PHY found\n");
@@ -408,6 +520,9 @@ ltq_etop_mdio_probe(struct net_device *dev)
| SUPPORTED_Autoneg
| SUPPORTED_MII
| SUPPORTED_TP);
+ if (ltq_has_gbit())
+ phydev->supported &= SUPPORTED_1000baseT_Half
+ | SUPPORTED_1000baseT_Full;
phydev->advertising = phydev->supported;
priv->phydev = phydev;
@@ -433,8 +548,13 @@ ltq_etop_mdio_init(struct net_device *dev)
}
priv->mii_bus->priv = dev;
- priv->mii_bus->read = ltq_etop_mdio_rd;
- priv->mii_bus->write = ltq_etop_mdio_wr;
+ if (ltq_has_gbit()) {
+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9;
+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9;
+ } else {
+ priv->mii_bus->read = ltq_etop_mdio_rd;
+ priv->mii_bus->write = ltq_etop_mdio_wr;
+ }
priv->mii_bus->name = "ltq_mii";
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
@@ -524,9 +644,9 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
struct ltq_etop_priv *priv = netdev_priv(dev);
struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
- int len;
unsigned long flags;
u32 byte_offset;
+ int len;
len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
@@ -700,7 +820,7 @@ ltq_etop_probe(struct platform_device *pdev)
{
struct net_device *dev;
struct ltq_etop_priv *priv;
- struct resource *res;
+ struct resource *res, *gbit_res;
int err;
int i;
@@ -728,6 +848,23 @@ ltq_etop_probe(struct platform_device *pdev)
goto err_out;
}
+ if (ltq_has_gbit()) {
+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!gbit_res) {
+ dev_err(&pdev->dev, "failed to get gbit resource\n");
+ err = -ENOENT;
+ goto err_out;
+ }
+ ltq_gbit_membase = devm_ioremap_nocache(&pdev->dev,
+ gbit_res->start, resource_size(gbit_res));
+ if (!ltq_gbit_membase) {
+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
+ pdev->id);
+ err = -ENOMEM;
+ goto err_out;
+ }
+ }
+
dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
strcpy(dev->name, "eth%d");
dev->netdev_ops = <q_eth_netdev_ops;
--
1.7.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 3/3] NET: MIPS: lantiq: return value of request_irq was not handled gracefully
2011-11-16 14:41 [PATCH 1/3] NET: MIPS: lantiq: make etop ethernet work on ase/ar9 John Crispin
@ 2011-11-16 14:41 ` John Crispin
0 siblings, 0 replies; 5+ messages in thread
From: John Crispin @ 2011-11-16 14:41 UTC (permalink / raw)
To: netdev; +Cc: John Crispin
The return values of request_irq() were not checked leading to the following
error message.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: netdev@vger.kernel.org
---
drivers/net/ethernet/lantiq_etop.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
index 9fd6779..dddb9fe 100644
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -312,6 +312,7 @@ ltq_etop_hw_init(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
unsigned int mii_mode = priv->pldata->mii_mode;
+ int err = 0;
int i;
ltq_pmu_enable(PMU_PPE);
@@ -356,7 +357,7 @@ ltq_etop_hw_init(struct net_device *dev)
ltq_dma_init_port(DMA_PORT_ETOP);
- for (i = 0; i < MAX_DMA_CHAN; i++) {
+ for (i = 0; i < MAX_DMA_CHAN && !err; i++) {
int irq = LTQ_DMA_ETOP + i;
struct ltq_etop_chan *ch = &priv->ch[i];
@@ -364,21 +365,22 @@ ltq_etop_hw_init(struct net_device *dev)
if (IS_TX(i)) {
ltq_dma_alloc_tx(&ch->dma);
- request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+ err = request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
"etop_tx", priv);
} else if (IS_RX(i)) {
ltq_dma_alloc_rx(&ch->dma);
for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
ch->dma.desc++)
if (ltq_etop_alloc_skb(ch))
- return -ENOMEM;
+ err = -ENOMEM;
ch->dma.desc = 0;
- request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+ err = request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
"etop_rx", priv);
}
- ch->dma.irq = irq;
+ if (!err)
+ ch->dma.irq = irq;
}
- return 0;
+ return err;
}
static void
--
1.7.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-11-18 8:53 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-17 16:42 [PATCH 1/3] NET: MIPS: lantiq: make etop ethernet work on ase/ar9 John Crispin
2011-11-17 16:42 ` [PATCH 2/3] NET: MIPS: lantiq: non existing phy was not handled gracefully John Crispin
2011-11-17 16:42 ` [PATCH 3/3] NET: MIPS: lantiq: return value of request_irq " John Crispin
2011-11-18 8:52 ` Sergei Shtylyov
-- strict thread matches above, loose matches on Subject: below --
2011-11-16 14:41 [PATCH 1/3] NET: MIPS: lantiq: make etop ethernet work on ase/ar9 John Crispin
2011-11-16 14:41 ` [PATCH 3/3] NET: MIPS: lantiq: return value of request_irq was not handled gracefully John Crispin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.