summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/ti
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/ti')
-rw-r--r--drivers/net/ethernet/ti/Kconfig4
-rw-r--r--drivers/net/ethernet/ti/cpmac.c279
-rw-r--r--drivers/net/ethernet/ti/cpsw.c45
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.c12
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.h4
-rw-r--r--drivers/net/ethernet/ti/cpts.c24
-rw-r--r--drivers/net/ethernet/ti/davinci_mdio.c21
-rw-r--r--drivers/net/ethernet/ti/tlan.c224
-rw-r--r--drivers/net/ethernet/ti/tlan.h5
9 files changed, 354 insertions, 264 deletions
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index 53150c25a96b..1769700a6070 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -5,7 +5,7 @@
config NET_VENDOR_TI
bool "Texas Instruments (TI) devices"
default y
- depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX))
+ depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX || ARCH_KEYSTONE))
---help---
If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from
@@ -32,7 +32,7 @@ config TI_DAVINCI_EMAC
config TI_DAVINCI_MDIO
tristate "TI DaVinci MDIO Support"
- depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX )
+ depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX || ARCH_KEYSTONE )
select PHYLIB
---help---
This driver supports TI's DaVinci MDIO module.
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c
index 7399a52f7c26..3809f4ec2820 100644
--- a/drivers/net/ethernet/ti/cpmac.c
+++ b/drivers/net/ethernet/ti/cpmac.c
@@ -67,42 +67,42 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
#define CPMAC_RX_CONTROL 0x0014
#define CPMAC_RX_TEARDOWN 0x0018
#define CPMAC_MBP 0x0100
-# define MBP_RXPASSCRC 0x40000000
-# define MBP_RXQOS 0x20000000
-# define MBP_RXNOCHAIN 0x10000000
-# define MBP_RXCMF 0x01000000
-# define MBP_RXSHORT 0x00800000
-# define MBP_RXCEF 0x00400000
-# define MBP_RXPROMISC 0x00200000
-# define MBP_PROMISCCHAN(channel) (((channel) & 0x7) << 16)
-# define MBP_RXBCAST 0x00002000
-# define MBP_BCASTCHAN(channel) (((channel) & 0x7) << 8)
-# define MBP_RXMCAST 0x00000020
-# define MBP_MCASTCHAN(channel) ((channel) & 0x7)
+#define MBP_RXPASSCRC 0x40000000
+#define MBP_RXQOS 0x20000000
+#define MBP_RXNOCHAIN 0x10000000
+#define MBP_RXCMF 0x01000000
+#define MBP_RXSHORT 0x00800000
+#define MBP_RXCEF 0x00400000
+#define MBP_RXPROMISC 0x00200000
+#define MBP_PROMISCCHAN(channel) (((channel) & 0x7) << 16)
+#define MBP_RXBCAST 0x00002000
+#define MBP_BCASTCHAN(channel) (((channel) & 0x7) << 8)
+#define MBP_RXMCAST 0x00000020
+#define MBP_MCASTCHAN(channel) ((channel) & 0x7)
#define CPMAC_UNICAST_ENABLE 0x0104
#define CPMAC_UNICAST_CLEAR 0x0108
#define CPMAC_MAX_LENGTH 0x010c
#define CPMAC_BUFFER_OFFSET 0x0110
#define CPMAC_MAC_CONTROL 0x0160
-# define MAC_TXPTYPE 0x00000200
-# define MAC_TXPACE 0x00000040
-# define MAC_MII 0x00000020
-# define MAC_TXFLOW 0x00000010
-# define MAC_RXFLOW 0x00000008
-# define MAC_MTEST 0x00000004
-# define MAC_LOOPBACK 0x00000002
-# define MAC_FDX 0x00000001
+#define MAC_TXPTYPE 0x00000200
+#define MAC_TXPACE 0x00000040
+#define MAC_MII 0x00000020
+#define MAC_TXFLOW 0x00000010
+#define MAC_RXFLOW 0x00000008
+#define MAC_MTEST 0x00000004
+#define MAC_LOOPBACK 0x00000002
+#define MAC_FDX 0x00000001
#define CPMAC_MAC_STATUS 0x0164
-# define MAC_STATUS_QOS 0x00000004
-# define MAC_STATUS_RXFLOW 0x00000002
-# define MAC_STATUS_TXFLOW 0x00000001
+#define MAC_STATUS_QOS 0x00000004
+#define MAC_STATUS_RXFLOW 0x00000002
+#define MAC_STATUS_TXFLOW 0x00000001
#define CPMAC_TX_INT_ENABLE 0x0178
#define CPMAC_TX_INT_CLEAR 0x017c
#define CPMAC_MAC_INT_VECTOR 0x0180
-# define MAC_INT_STATUS 0x00080000
-# define MAC_INT_HOST 0x00040000
-# define MAC_INT_RX 0x00020000
-# define MAC_INT_TX 0x00010000
+#define MAC_INT_STATUS 0x00080000
+#define MAC_INT_HOST 0x00040000
+#define MAC_INT_RX 0x00020000
+#define MAC_INT_TX 0x00010000
#define CPMAC_MAC_EOI_VECTOR 0x0184
#define CPMAC_RX_INT_ENABLE 0x0198
#define CPMAC_RX_INT_CLEAR 0x019c
@@ -118,8 +118,8 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
#define CPMAC_TX_ACK(channel) (0x0640 + (channel) * 4)
#define CPMAC_RX_ACK(channel) (0x0660 + (channel) * 4)
#define CPMAC_REG_END 0x0680
-/*
- * Rx/Tx statistics
+
+/* Rx/Tx statistics
* TODO: use some of them to fill stats in cpmac_stats()
*/
#define CPMAC_STATS_RX_GOOD 0x0200
@@ -157,24 +157,24 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
/* MDIO bus */
#define CPMAC_MDIO_VERSION 0x0000
#define CPMAC_MDIO_CONTROL 0x0004
-# define MDIOC_IDLE 0x80000000
-# define MDIOC_ENABLE 0x40000000
-# define MDIOC_PREAMBLE 0x00100000
-# define MDIOC_FAULT 0x00080000
-# define MDIOC_FAULTDETECT 0x00040000
-# define MDIOC_INTTEST 0x00020000
-# define MDIOC_CLKDIV(div) ((div) & 0xff)
+#define MDIOC_IDLE 0x80000000
+#define MDIOC_ENABLE 0x40000000
+#define MDIOC_PREAMBLE 0x00100000
+#define MDIOC_FAULT 0x00080000
+#define MDIOC_FAULTDETECT 0x00040000
+#define MDIOC_INTTEST 0x00020000
+#define MDIOC_CLKDIV(div) ((div) & 0xff)
#define CPMAC_MDIO_ALIVE 0x0008
#define CPMAC_MDIO_LINK 0x000c
#define CPMAC_MDIO_ACCESS(channel) (0x0080 + (channel) * 8)
-# define MDIO_BUSY 0x80000000
-# define MDIO_WRITE 0x40000000
-# define MDIO_REG(reg) (((reg) & 0x1f) << 21)
-# define MDIO_PHY(phy) (((phy) & 0x1f) << 16)
-# define MDIO_DATA(data) ((data) & 0xffff)
+#define MDIO_BUSY 0x80000000
+#define MDIO_WRITE 0x40000000
+#define MDIO_REG(reg) (((reg) & 0x1f) << 21)
+#define MDIO_PHY(phy) (((phy) & 0x1f) << 16)
+#define MDIO_DATA(data) ((data) & 0xffff)
#define CPMAC_MDIO_PHYSEL(channel) (0x0084 + (channel) * 8)
-# define PHYSEL_LINKSEL 0x00000040
-# define PHYSEL_LINKINT 0x00000020
+#define PHYSEL_LINKSEL 0x00000040
+#define PHYSEL_LINKINT 0x00000020
struct cpmac_desc {
u32 hw_next;
@@ -224,12 +224,12 @@ static void cpmac_dump_regs(struct net_device *dev)
{
int i;
struct cpmac_priv *priv = netdev_priv(dev);
+
for (i = 0; i < CPMAC_REG_END; i += 4) {
if (i % 16 == 0) {
if (i)
- pr_cont("\n");
- printk(KERN_DEBUG "%s: reg[%p]:", dev->name,
- priv->regs + i);
+ printk("\n");
+ printk("%s: reg[%p]:", dev->name, priv->regs + i);
}
printk(" %08x", cpmac_read(priv->regs, i));
}
@@ -239,7 +239,8 @@ static void cpmac_dump_regs(struct net_device *dev)
static void cpmac_dump_desc(struct net_device *dev, struct cpmac_desc *desc)
{
int i;
- printk(KERN_DEBUG "%s: desc[%p]:", dev->name, desc);
+
+ printk("%s: desc[%p]:", dev->name, desc);
for (i = 0; i < sizeof(*desc) / 4; i++)
printk(" %08x", ((u32 *)desc)[i]);
printk("\n");
@@ -249,6 +250,7 @@ static void cpmac_dump_all_desc(struct net_device *dev)
{
struct cpmac_priv *priv = netdev_priv(dev);
struct cpmac_desc *dump = priv->rx_head;
+
do {
cpmac_dump_desc(dev, dump);
dump = dump->next;
@@ -258,13 +260,13 @@ static void cpmac_dump_all_desc(struct net_device *dev)
static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb)
{
int i;
- printk(KERN_DEBUG "%s: skb 0x%p, len=%d\n", dev->name, skb, skb->len);
+
+ printk("%s: skb 0x%p, len=%d\n", dev->name, skb, skb->len);
for (i = 0; i < skb->len; i++) {
if (i % 16 == 0) {
if (i)
- pr_cont("\n");
- printk(KERN_DEBUG "%s: data[%p]:", dev->name,
- skb->data + i);
+ printk("\n");
+ printk("%s: data[%p]:", dev->name, skb->data + i);
}
printk(" %02x", ((u8 *)skb->data)[i]);
}
@@ -281,6 +283,7 @@ static int cpmac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
MDIO_PHY(phy_id));
while ((val = cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0))) & MDIO_BUSY)
cpu_relax();
+
return MDIO_DATA(val);
}
@@ -291,6 +294,7 @@ static int cpmac_mdio_write(struct mii_bus *bus, int phy_id,
cpu_relax();
cpmac_write(bus->priv, CPMAC_MDIO_ACCESS(0), MDIO_BUSY | MDIO_WRITE |
MDIO_REG(reg) | MDIO_PHY(phy_id) | MDIO_DATA(val));
+
return 0;
}
@@ -300,12 +304,13 @@ static int cpmac_mdio_reset(struct mii_bus *bus)
cpmac_clk = clk_get(&bus->dev, "cpmac");
if (IS_ERR(cpmac_clk)) {
- printk(KERN_ERR "unable to get cpmac clock\n");
+ pr_err("unable to get cpmac clock\n");
return -1;
}
ar7_device_reset(AR7_RESET_BIT_MDIO);
cpmac_write(bus->priv, CPMAC_MDIO_CONTROL, MDIOC_ENABLE |
MDIOC_CLKDIV(clk_get_rate(cpmac_clk) / 2200000 - 1));
+
return 0;
}
@@ -331,8 +336,7 @@ static void cpmac_set_multicast_list(struct net_device *dev)
cpmac_write(priv->regs, CPMAC_MAC_HASH_LO, 0xffffffff);
cpmac_write(priv->regs, CPMAC_MAC_HASH_HI, 0xffffffff);
} else {
- /*
- * cpmac uses some strange mac address hashing
+ /* cpmac uses some strange mac address hashing
* (not crc32)
*/
netdev_for_each_mc_addr(ha, dev) {
@@ -369,8 +373,8 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv,
cpmac_write(priv->regs, CPMAC_RX_ACK(0), (u32)desc->mapping);
if (unlikely(!desc->datalen)) {
if (netif_msg_rx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: rx: spurious interrupt\n",
- priv->dev->name);
+ netdev_warn(priv->dev, "rx: spurious interrupt\n");
+
return NULL;
}
@@ -390,15 +394,14 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv,
DMA_FROM_DEVICE);
desc->hw_data = (u32)desc->data_mapping;
if (unlikely(netif_msg_pktdata(priv))) {
- printk(KERN_DEBUG "%s: received packet:\n",
- priv->dev->name);
+ netdev_dbg(priv->dev, "received packet:\n");
cpmac_dump_skb(priv->dev, result);
}
} else {
if (netif_msg_rx_err(priv) && net_ratelimit())
- printk(KERN_WARNING
- "%s: low on skbs, dropping packet\n",
- priv->dev->name);
+ netdev_warn(priv->dev,
+ "low on skbs, dropping packet\n");
+
priv->dev->stats.rx_dropped++;
}
@@ -418,8 +421,8 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
spin_lock(&priv->rx_lock);
if (unlikely(!priv->rx_head)) {
if (netif_msg_rx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: rx: polling, but no queue\n",
- priv->dev->name);
+ netdev_warn(priv->dev, "rx: polling, but no queue\n");
+
spin_unlock(&priv->rx_lock);
napi_complete(napi);
return 0;
@@ -432,15 +435,15 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
if ((desc->dataflags & CPMAC_EOQ) != 0) {
/* The last update to eoq->hw_next didn't happen
- * soon enough, and the receiver stopped here.
- *Remember this descriptor so we can restart
- * the receiver after freeing some space.
- */
+ * soon enough, and the receiver stopped here.
+ * Remember this descriptor so we can restart
+ * the receiver after freeing some space.
+ */
if (unlikely(restart)) {
if (netif_msg_rx_err(priv))
- printk(KERN_ERR "%s: poll found a"
- " duplicate EOQ: %p and %p\n",
- priv->dev->name, restart, desc);
+ netdev_err(priv->dev, "poll found a"
+ " duplicate EOQ: %p and %p\n",
+ restart, desc);
goto fatal_error;
}
@@ -457,25 +460,27 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
if (desc != priv->rx_head) {
/* We freed some buffers, but not the whole ring,
- * add what we did free to the rx list */
+ * add what we did free to the rx list
+ */
desc->prev->hw_next = (u32)0;
priv->rx_head->prev->hw_next = priv->rx_head->mapping;
}
/* Optimization: If we did not actually process an EOQ (perhaps because
* of quota limits), check to see if the tail of the queue has EOQ set.
- * We should immediately restart in that case so that the receiver can
- * restart and run in parallel with more packet processing.
- * This lets us handle slightly larger bursts before running
- * out of ring space (assuming dev->weight < ring_size) */
+ * We should immediately restart in that case so that the receiver can
+ * restart and run in parallel with more packet processing.
+ * This lets us handle slightly larger bursts before running
+ * out of ring space (assuming dev->weight < ring_size)
+ */
if (!restart &&
(priv->rx_head->prev->dataflags & (CPMAC_OWN|CPMAC_EOQ))
== CPMAC_EOQ &&
(priv->rx_head->dataflags & CPMAC_OWN) != 0) {
/* reset EOQ so the poll loop (above) doesn't try to
- * restart this when it eventually gets to this descriptor.
- */
+ * restart this when it eventually gets to this descriptor.
+ */
priv->rx_head->prev->dataflags &= ~CPMAC_EOQ;
restart = priv->rx_head;
}
@@ -484,15 +489,13 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
priv->dev->stats.rx_errors++;
priv->dev->stats.rx_fifo_errors++;
if (netif_msg_rx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: rx dma ring overrun\n",
- priv->dev->name);
+ netdev_warn(priv->dev, "rx dma ring overrun\n");
if (unlikely((restart->dataflags & CPMAC_OWN) == 0)) {
if (netif_msg_drv(priv))
- printk(KERN_ERR "%s: cpmac_poll is trying to "
- "restart rx from a descriptor that's "
- "not free: %p\n",
- priv->dev->name, restart);
+ netdev_err(priv->dev, "cpmac_poll is trying "
+ "to restart rx from a descriptor "
+ "that's not free: %p\n", restart);
goto fatal_error;
}
@@ -502,11 +505,12 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
priv->rx_head = desc;
spin_unlock(&priv->rx_lock);
if (unlikely(netif_msg_rx_status(priv)))
- printk(KERN_DEBUG "%s: poll processed %d packets\n",
- priv->dev->name, received);
+ netdev_dbg(priv->dev, "poll processed %d packets\n", received);
+
if (processed == 0) {
/* we ran out of packets to read,
- * revert to interrupt-driven mode */
+ * revert to interrupt-driven mode
+ */
napi_complete(napi);
cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
return 0;
@@ -516,16 +520,15 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
fatal_error:
/* Something went horribly wrong.
- * Reset hardware to try to recover rather than wedging. */
-
+ * Reset hardware to try to recover rather than wedging.
+ */
if (netif_msg_drv(priv)) {
- printk(KERN_ERR "%s: cpmac_poll is confused. "
- "Resetting hardware\n", priv->dev->name);
+ netdev_err(priv->dev, "cpmac_poll is confused. "
+ "Resetting hardware\n");
cpmac_dump_all_desc(priv->dev);
- printk(KERN_DEBUG "%s: RX_PTR(0)=0x%08x RX_ACK(0)=0x%08x\n",
- priv->dev->name,
- cpmac_read(priv->regs, CPMAC_RX_PTR(0)),
- cpmac_read(priv->regs, CPMAC_RX_ACK(0)));
+ netdev_dbg(priv->dev, "RX_PTR(0)=0x%08x RX_ACK(0)=0x%08x\n",
+ cpmac_read(priv->regs, CPMAC_RX_PTR(0)),
+ cpmac_read(priv->regs, CPMAC_RX_ACK(0)));
}
spin_unlock(&priv->rx_lock);
@@ -537,6 +540,7 @@ fatal_error:
cpmac_hw_stop(priv->dev);
if (!schedule_work(&priv->reset_work))
atomic_dec(&priv->reset_pending);
+
return 0;
}
@@ -560,8 +564,8 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
desc = &priv->desc_ring[queue];
if (unlikely(desc->dataflags & CPMAC_OWN)) {
if (netif_msg_tx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: tx dma ring full\n",
- dev->name);
+ netdev_warn(dev, "tx dma ring full\n");
+
return NETDEV_TX_BUSY;
}
@@ -575,8 +579,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
desc->datalen = len;
desc->buflen = len;
if (unlikely(netif_msg_tx_queued(priv)))
- printk(KERN_DEBUG "%s: sending 0x%p, len=%d\n", dev->name, skb,
- skb->len);
+ netdev_dbg(dev, "sending 0x%p, len=%d\n", skb, skb->len);
if (unlikely(netif_msg_hw(priv)))
cpmac_dump_desc(dev, desc);
if (unlikely(netif_msg_pktdata(priv)))
@@ -602,8 +605,8 @@ static void cpmac_end_xmit(struct net_device *dev, int queue)
DMA_TO_DEVICE);
if (unlikely(netif_msg_tx_done(priv)))
- printk(KERN_DEBUG "%s: sent 0x%p, len=%d\n", dev->name,
- desc->skb, desc->skb->len);
+ netdev_dbg(dev, "sent 0x%p, len=%d\n",
+ desc->skb, desc->skb->len);
dev_kfree_skb_irq(desc->skb);
desc->skb = NULL;
@@ -611,8 +614,7 @@ static void cpmac_end_xmit(struct net_device *dev, int queue)
netif_wake_subqueue(dev, queue);
} else {
if (netif_msg_tx_err(priv) && net_ratelimit())
- printk(KERN_WARNING
- "%s: end_xmit: spurious interrupt\n", dev->name);
+ netdev_warn(dev, "end_xmit: spurious interrupt\n");
if (__netif_subqueue_stopped(dev, queue))
netif_wake_subqueue(dev, queue);
}
@@ -687,14 +689,14 @@ static void cpmac_clear_rx(struct net_device *dev)
struct cpmac_priv *priv = netdev_priv(dev);
struct cpmac_desc *desc;
int i;
+
if (unlikely(!priv->rx_head))
return;
desc = priv->rx_head;
for (i = 0; i < priv->ring_size; i++) {
if ((desc->dataflags & CPMAC_OWN) == 0) {
if (netif_msg_rx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: packet dropped\n",
- dev->name);
+ netdev_warn(dev, "packet dropped\n");
if (unlikely(netif_msg_hw(priv)))
cpmac_dump_desc(dev, desc);
desc->dataflags = CPMAC_OWN;
@@ -710,6 +712,7 @@ static void cpmac_clear_tx(struct net_device *dev)
{
struct cpmac_priv *priv = netdev_priv(dev);
int i;
+
if (unlikely(!priv->desc_ring))
return;
for (i = 0; i < CPMAC_QUEUES; i++) {
@@ -751,16 +754,16 @@ static void cpmac_check_status(struct net_device *dev)
if (rx_code || tx_code) {
if (netif_msg_drv(priv) && net_ratelimit()) {
/* Can't find any documentation on what these
- *error codes actually are. So just log them and hope..
+ * error codes actually are. So just log them and hope..
*/
if (rx_code)
- printk(KERN_WARNING "%s: host error %d on rx "
- "channel %d (macstatus %08x), resetting\n",
- dev->name, rx_code, rx_channel, macstatus);
+ netdev_warn(dev, "host error %d on rx "
+ "channel %d (macstatus %08x), resetting\n",
+ rx_code, rx_channel, macstatus);
if (tx_code)
- printk(KERN_WARNING "%s: host error %d on tx "
- "channel %d (macstatus %08x), resetting\n",
- dev->name, tx_code, tx_channel, macstatus);
+ netdev_warn(dev, "host error %d on tx "
+ "channel %d (macstatus %08x), resetting\n",
+ tx_code, tx_channel, macstatus);
}
netif_tx_stop_all_queues(dev);
@@ -785,8 +788,7 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
status = cpmac_read(priv->regs, CPMAC_MAC_INT_VECTOR);
if (unlikely(netif_msg_intr(priv)))
- printk(KERN_DEBUG "%s: interrupt status: 0x%08x\n", dev->name,
- status);
+ netdev_dbg(dev, "interrupt status: 0x%08x\n", status);
if (status & MAC_INT_TX)
cpmac_end_xmit(dev, (status & 7));
@@ -815,7 +817,7 @@ static void cpmac_tx_timeout(struct net_device *dev)
dev->stats.tx_errors++;
spin_unlock(&priv->lock);
if (netif_msg_tx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: transmit timeout\n", dev->name);
+ netdev_warn(dev, "transmit timeout\n");
atomic_inc(&priv->reset_pending);
barrier();
@@ -829,6 +831,7 @@ static void cpmac_tx_timeout(struct net_device *dev)
static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct cpmac_priv *priv = netdev_priv(dev);
+
if (!(netif_running(dev)))
return -EINVAL;
if (!priv->phy)
@@ -884,6 +887,7 @@ static int cpmac_set_ringparam(struct net_device *dev,
if (netif_running(dev))
return -EBUSY;
priv->ring_size = ring->rx_pending;
+
return 0;
}
@@ -951,8 +955,8 @@ static int cpmac_open(struct net_device *dev)
mem = platform_get_resource_byname(priv->pdev, IORESOURCE_MEM, "regs");
if (!request_mem_region(mem->start, resource_size(mem), dev->name)) {
if (netif_msg_drv(priv))
- printk(KERN_ERR "%s: failed to request registers\n",
- dev->name);
+ netdev_err(dev, "failed to request registers\n");
+
res = -ENXIO;
goto fail_reserve;
}
@@ -960,8 +964,8 @@ static int cpmac_open(struct net_device *dev)
priv->regs = ioremap(mem->start, resource_size(mem));
if (!priv->regs) {
if (netif_msg_drv(priv))
- printk(KERN_ERR "%s: failed to remap registers\n",
- dev->name);
+ netdev_err(dev, "failed to remap registers\n");
+
res = -ENXIO;
goto fail_remap;
}
@@ -1003,8 +1007,8 @@ static int cpmac_open(struct net_device *dev)
res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, dev->name, dev);
if (res) {
if (netif_msg_drv(priv))
- printk(KERN_ERR "%s: failed to obtain irq\n",
- dev->name);
+ netdev_err(dev, "failed to obtain irq\n");
+
goto fail_irq;
}
@@ -1077,6 +1081,7 @@ static int cpmac_stop(struct net_device *dev)
dma_free_coherent(&dev->dev, sizeof(struct cpmac_desc) *
(CPMAC_QUEUES + priv->ring_size),
priv->desc_ring, priv->dma_ring);
+
return 0;
}
@@ -1121,7 +1126,7 @@ static int cpmac_probe(struct platform_device *pdev)
if (phy_id == PHY_MAX_ADDR) {
dev_err(&pdev->dev, "no PHY present, falling back "
- "to switch on MDIO bus 0\n");
+ "to switch on MDIO bus 0\n");
strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); /* fixed phys bus */
phy_id = pdev->id;
}
@@ -1137,7 +1142,7 @@ static int cpmac_probe(struct platform_device *pdev)
mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
if (!mem) {
rc = -ENODEV;
- goto fail;
+ goto out;
}
dev->irq = platform_get_irq_byname(pdev, "irq");
@@ -1162,44 +1167,48 @@ static int cpmac_probe(struct platform_device *pdev)
if (IS_ERR(priv->phy)) {
if (netif_msg_drv(priv))
- printk(KERN_ERR "%s: Could not attach to PHY\n",
- dev->name);
+ dev_err(&pdev->dev, "Could not attach to PHY\n");
+
rc = PTR_ERR(priv->phy);
- goto fail;
+ goto out;
}
rc = register_netdev(dev);
if (rc) {
- printk(KERN_ERR "cpmac: error %i registering device %s\n", rc,
- dev->name);
+ dev_err(&pdev->dev, "Could not register net device\n");
goto fail;
}
if (netif_msg_probe(priv)) {
- printk(KERN_INFO
- "cpmac: device %s (regs: %p, irq: %d, phy: %s, "
- "mac: %pM)\n", dev->name, (void *)mem->start, dev->irq,
- priv->phy_name, dev->dev_addr);
+ dev_info(&pdev->dev, "regs: %p, irq: %d, phy: %s, "
+ "mac: %pM\n", (void *)mem->start, dev->irq,
+ priv->phy_name, dev->dev_addr);
}
+
return 0;
fail:
free_netdev(dev);
+out:
return rc;
}
static int cpmac_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
+
unregister_netdev(dev);
free_netdev(dev);
+
return 0;
}
static struct platform_driver cpmac_driver = {
- .driver.name = "cpmac",
- .driver.owner = THIS_MODULE,
- .probe = cpmac_probe,
+ .driver = {
+ .name = "cpmac",
+ .owner = THIS_MODULE,
+ },
+ .probe = cpmac_probe,
.remove = cpmac_remove,
};
@@ -1221,7 +1230,7 @@ int cpmac_init(void)
cpmac_mii->priv = ioremap(AR7_REGS_MDIO, 256);
if (!cpmac_mii->priv) {
- printk(KERN_ERR "Can't ioremap mdio registers\n");
+ pr_err("Can't ioremap mdio registers\n");
res = -ENXIO;
goto fail_alloc;
}
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index b988d16cd34e..999fb72688d2 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -884,14 +884,16 @@ static int cpsw_set_coalesce(struct net_device *ndev,
u32 addnl_dvdr = 1;
u32 coal_intvl = 0;
- if (!coal->rx_coalesce_usecs)
- return -EINVAL;
-
coal_intvl = coal->rx_coalesce_usecs;
int_ctrl = readl(&priv->wr_regs->int_control);
prescale = priv->bus_freq_mhz * 4;
+ if (!coal->rx_coalesce_usecs) {
+ int_ctrl &= ~(CPSW_INTPRESCALE_MASK | CPSW_INTPACEEN);
+ goto update_return;
+ }
+
if (coal_intvl < CPSW_CMINTMIN_INTVL)
coal_intvl = CPSW_CMINTMIN_INTVL;
@@ -919,6 +921,8 @@ static int cpsw_set_coalesce(struct net_device *ndev,
int_ctrl |= CPSW_INTPACEEN;
int_ctrl &= (~CPSW_INTPRESCALE_MASK);
int_ctrl |= (prescale & CPSW_INTPRESCALE_MASK);
+
+update_return:
writel(int_ctrl, &priv->wr_regs->int_control);
cpsw_notice(priv, timer, "Set coalesce to %d usecs.\n", coal_intvl);
@@ -999,17 +1003,6 @@ static void cpsw_get_ethtool_stats(struct net_device *ndev,
}
}
-static inline int __show_stat(char *buf, int maxlen, const char *name, u32 val)
-{
- static char *leader = "........................................";
-
- if (!val)
- return 0;
- else
- return snprintf(buf, maxlen, "%s %s %10d\n", name,
- leader + strlen(name), val);
-}
-
static int cpsw_common_res_usage_state(struct cpsw_priv *priv)
{
u32 i;
@@ -1671,14 +1664,34 @@ static const struct net_device_ops cpsw_netdev_ops = {
.ndo_vlan_rx_kill_vid = cpsw_ndo_vlan_rx_kill_vid,
};
+static int cpsw_get_regs_len(struct net_device *ndev)
+{
+ struct cpsw_priv *priv = netdev_priv(ndev);
+
+ return priv->data.ale_entries * ALE_ENTRY_WORDS * sizeof(u32);
+}
+
+static void cpsw_get_regs(struct net_device *ndev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct cpsw_priv *priv = netdev_priv(ndev);
+ u32 *reg = p;
+
+ /* update CPSW IP version */
+ regs->version = priv->version;
+
+ cpsw_ale_dump(priv->ale, reg);
+}
+
static void cpsw_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
{
struct cpsw_priv *priv = netdev_priv(ndev);
- strlcpy(info->driver, "TI CPSW Driver v1.0", sizeof(info->driver));
+ strlcpy(info->driver, "cpsw", sizeof(info->driver));
strlcpy(info->version, "1.0", sizeof(info->version));
strlcpy(info->bus_info, priv->pdev->name, sizeof(info->bus_info));
+ info->regdump_len = cpsw_get_regs_len(ndev);
}
static u32 cpsw_get_msglevel(struct net_device *ndev)
@@ -1786,6 +1799,8 @@ static const struct ethtool_ops cpsw_ethtool_ops = {
.get_ethtool_stats = cpsw_get_ethtool_stats,
.get_wol = cpsw_get_wol,
.set_wol = cpsw_set_wol,
+ .get_regs_len = cpsw_get_regs_len,
+ .get_regs = cpsw_get_regs,
};
static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index 7f893069c418..0579b2243bb6 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -25,8 +25,6 @@
#include "cpsw_ale.h"
#define BITMASK(bits) (BIT(bits) - 1)
-#define ALE_ENTRY_BITS 68
-#define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32)
#define ALE_VERSION_MAJOR(rev) ((rev >> 8) & 0xff)
#define ALE_VERSION_MINOR(rev) (rev & 0xff)
@@ -763,3 +761,13 @@ int cpsw_ale_destroy(struct cpsw_ale *ale)
kfree(ale);
return 0;
}
+
+void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data)
+{
+ int i;
+
+ for (i = 0; i < ale->params.ale_entries; i++) {
+ cpsw_ale_read(ale, i, data);
+ data += ALE_ENTRY_WORDS;
+ }
+}
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h
index de409c33b250..31cf43cab42e 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.h
+++ b/drivers/net/ethernet/ti/cpsw_ale.h
@@ -80,6 +80,9 @@ enum cpsw_ale_port_state {
#define ALE_MCAST_FWD_LEARN 2
#define ALE_MCAST_FWD_2 3
+#define ALE_ENTRY_BITS 68
+#define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32)
+
struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params);
int cpsw_ale_destroy(struct cpsw_ale *ale);
@@ -104,5 +107,6 @@ int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port);
int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control);
int cpsw_ale_control_set(struct cpsw_ale *ale, int port,
int control, int value);
+void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data);
#endif
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 6b56f85951e5..ab92f67da035 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -256,23 +256,21 @@ static int cpts_match(struct sk_buff *skb, unsigned int ptp_class,
u16 ts_seqid, u8 ts_msgtype)
{
u16 *seqid;
- unsigned int offset;
+ unsigned int offset = 0;
u8 *msgtype, *data = skb->data;
- switch (ptp_class) {
- case PTP_CLASS_V1_IPV4:
- case PTP_CLASS_V2_IPV4:
- offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
- break;
- case PTP_CLASS_V1_IPV6:
- case PTP_CLASS_V2_IPV6:
- offset = OFF_PTP6;
+ if (ptp_class & PTP_CLASS_VLAN)
+ offset += VLAN_HLEN;
+
+ switch (ptp_class & PTP_CLASS_PMASK) {
+ case PTP_CLASS_IPV4:
+ offset += ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
break;
- case PTP_CLASS_V2_L2:
- offset = ETH_HLEN;
+ case PTP_CLASS_IPV6:
+ offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
break;
- case PTP_CLASS_V2_VLAN:
- offset = ETH_HLEN + VLAN_HLEN;
+ case PTP_CLASS_L2:
+ offset += ETH_HLEN;
break;
default:
return 0;
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 735dc53d4b01..2791f6f2db11 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -38,6 +38,7 @@
#include <linux/davinci_emac.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_mdio.h>
#include <linux/pinctrl/consumer.h>
/*
@@ -95,6 +96,10 @@ struct davinci_mdio_data {
struct mii_bus *bus;
bool suspended;
unsigned long access_time; /* jiffies */
+ /* Indicates that driver shouldn't modify phy_mask in case
+ * if MDIO bus is registered from DT.
+ */
+ bool skip_scan;
};
static void __davinci_mdio_reset(struct davinci_mdio_data *data)
@@ -144,6 +149,9 @@ static int davinci_mdio_reset(struct mii_bus *bus)
dev_info(data->dev, "davinci mdio revision %d.%d\n",
(ver >> 8) & 0xff, ver & 0xff);
+ if (data->skip_scan)
+ return 0;
+
/* get phy mask from the alive register */
phy_mask = __raw_readl(&data->regs->alive);
if (phy_mask) {
@@ -369,8 +377,17 @@ static int davinci_mdio_probe(struct platform_device *pdev)
goto bail_out;
}
- /* register the mii bus */
- ret = mdiobus_register(data->bus);
+ /* register the mii bus
+ * Create PHYs from DT only in case if PHY child nodes are explicitly
+ * defined to support backward compatibility with DTs which assume that
+ * Davinci MDIO will always scan the bus for PHYs detection.
+ */
+ if (dev->of_node && of_get_child_count(dev->of_node)) {
+ data->skip_scan = true;
+ ret = of_mdiobus_register(data->bus, dev->of_node);
+ } else {
+ ret = mdiobus_register(data->bus);
+ }
if (ret)
goto bail_out;
diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c
index 62b19be5183d..6078342fe3f2 100644
--- a/drivers/net/ethernet/ti/tlan.c
+++ b/drivers/net/ethernet/ti/tlan.c
@@ -69,10 +69,6 @@ MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
MODULE_LICENSE("GPL");
-
-/* Define this to enable Link beat monitoring */
-#undef MONITOR
-
/* Turn on debugging. See Documentation/networking/tlan.txt for details */
static int debug;
module_param(debug, int, 0);
@@ -107,8 +103,10 @@ static struct board {
{ "Compaq Netelligent 10/100 TX Embedded UTP",
TLAN_ADAPTER_NONE, 0x83 },
{ "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
- { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 },
- { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xf8 },
+ { "Olicom OC-2325", TLAN_ADAPTER_ACTIVITY_LED |
+ TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 },
+ { "Olicom OC-2326", TLAN_ADAPTER_ACTIVITY_LED |
+ TLAN_ADAPTER_USE_INTERN_10, 0xf8 },
{ "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
{ "Compaq Netelligent 10 T/2 PCI UTP/coax", TLAN_ADAPTER_NONE, 0x83 },
{ "Compaq NetFlex-3/E",
@@ -192,9 +190,7 @@ static void tlan_phy_power_up(struct net_device *);
static void tlan_phy_reset(struct net_device *);
static void tlan_phy_start_link(struct net_device *);
static void tlan_phy_finish_auto_neg(struct net_device *);
-#ifdef MONITOR
-static void tlan_phy_monitor(struct net_device *);
-#endif
+static void tlan_phy_monitor(unsigned long);
/*
static int tlan_phy_nop(struct net_device *);
@@ -337,6 +333,7 @@ static void tlan_stop(struct net_device *dev)
{
struct tlan_priv *priv = netdev_priv(dev);
+ del_timer_sync(&priv->media_timer);
tlan_read_and_clear_stats(dev, TLAN_RECORD);
outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
/* Reset and power down phy */
@@ -368,8 +365,10 @@ static int tlan_suspend(struct pci_dev *pdev, pm_message_t state)
static int tlan_resume(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
+ int rc = pci_enable_device(pdev);
- pci_set_power_state(pdev, PCI_D0);
+ if (rc)
+ return rc;
pci_restore_state(pdev);
pci_enable_wake(pdev, PCI_D0, 0);
netif_device_attach(dev);
@@ -781,7 +780,43 @@ static const struct net_device_ops tlan_netdev_ops = {
#endif
};
+static void tlan_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct tlan_priv *priv = netdev_priv(dev);
+
+ strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+ if (priv->pci_dev)
+ strlcpy(info->bus_info, pci_name(priv->pci_dev),
+ sizeof(info->bus_info));
+ else
+ strlcpy(info->bus_info, "EISA", sizeof(info->bus_info));
+ info->eedump_len = TLAN_EEPROM_SIZE;
+}
+
+static int tlan_get_eeprom_len(struct net_device *dev)
+{
+ return TLAN_EEPROM_SIZE;
+}
+
+static int tlan_get_eeprom(struct net_device *dev,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ int i;
+
+ for (i = 0; i < TLAN_EEPROM_SIZE; i++)
+ if (tlan_ee_read_byte(dev, i, &data[i]))
+ return -EIO;
+ return 0;
+}
+
+static const struct ethtool_ops tlan_ethtool_ops = {
+ .get_drvinfo = tlan_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_eeprom_len = tlan_get_eeprom_len,
+ .get_eeprom = tlan_get_eeprom,
+};
/***************************************************************
* tlan_init
@@ -830,7 +865,7 @@ static int tlan_init(struct net_device *dev)
priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS;
err = 0;
- for (i = 0; i < 6 ; i++)
+ for (i = 0; i < ETH_ALEN; i++)
err |= tlan_ee_read_byte(dev,
(u8) priv->adapter->addr_ofs + i,
(u8 *) &dev->dev_addr[i]);
@@ -838,12 +873,20 @@ static int tlan_init(struct net_device *dev)
pr_err("%s: Error reading MAC from eeprom: %d\n",
dev->name, err);
}
- dev->addr_len = 6;
+ /* Olicom OC-2325/OC-2326 have the address byte-swapped */
+ if (priv->adapter->addr_ofs == 0xf8) {
+ for (i = 0; i < ETH_ALEN; i += 2) {
+ char tmp = dev->dev_addr[i];
+ dev->dev_addr[i] = dev->dev_addr[i + 1];
+ dev->dev_addr[i + 1] = tmp;
+ }
+ }
netif_carrier_off(dev);
/* Device methods */
dev->netdev_ops = &tlan_netdev_ops;
+ dev->ethtool_ops = &tlan_ethtool_ops;
dev->watchdog_timeo = TX_TIMEOUT;
return 0;
@@ -886,6 +929,7 @@ static int tlan_open(struct net_device *dev)
}
init_timer(&priv->timer);
+ init_timer(&priv->media_timer);
tlan_start(dev);
@@ -1156,9 +1200,6 @@ static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id)
static int tlan_close(struct net_device *dev)
{
- struct tlan_priv *priv = netdev_priv(dev);
-
- priv->neg_be_verbose = 0;
tlan_stop(dev);
free_irq(dev->irq, dev);
@@ -1808,11 +1849,6 @@ static void tlan_timer(unsigned long data)
priv->timer.function = NULL;
switch (priv->timer_type) {
-#ifdef MONITOR
- case TLAN_TIMER_LINK_BEAT:
- tlan_phy_monitor(dev);
- break;
-#endif
case TLAN_TIMER_PHY_PDOWN:
tlan_phy_power_down(dev);
break;
@@ -1856,8 +1892,6 @@ static void tlan_timer(unsigned long data)
}
-
-
/*****************************************************************************
******************************************************************************
@@ -2205,7 +2239,9 @@ tlan_reset_adapter(struct net_device *dev)
}
}
- if (priv->phy_num == 0)
+ /* don't power down internal PHY if we're going to use it */
+ if (priv->phy_num == 0 ||
+ (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))
data |= TLAN_NET_CFG_PHY_EN;
tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
@@ -2255,42 +2291,39 @@ tlan_finish_reset(struct net_device *dev)
tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
udelay(1000);
tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
- if ((status & MII_GS_LINK) &&
- /* We only support link info on Nat.Sem. PHY's */
- (tlphy_id1 == NAT_SEM_ID1) &&
- (tlphy_id2 == NAT_SEM_ID2)) {
- tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner);
- tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par);
-
- netdev_info(dev,
- "Link active with %s %uMbps %s-Duplex\n",
- !(tlphy_par & TLAN_PHY_AN_EN_STAT)
- ? "forced" : "Autonegotiation enabled,",
- tlphy_par & TLAN_PHY_SPEED_100
- ? 100 : 10,
- tlphy_par & TLAN_PHY_DUPLEX_FULL
- ? "Full" : "Half");
-
- if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
- netdev_info(dev, "Partner capability:");
- for (i = 5; i < 10; i++)
- if (partner & (1 << i))
- pr_cont(" %s", media[i-5]);
- pr_cont("\n");
- }
-
- tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
- TLAN_LED_LINK);
-#ifdef MONITOR
- /* We have link beat..for now anyway */
- priv->link = 1;
- /*Enabling link beat monitoring */
- tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT);
-#endif
- } else if (status & MII_GS_LINK) {
- netdev_info(dev, "Link active\n");
- tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
- TLAN_LED_LINK);
+ if (status & MII_GS_LINK) {
+ /* We only support link info on Nat.Sem. PHY's */
+ if ((tlphy_id1 == NAT_SEM_ID1) &&
+ (tlphy_id2 == NAT_SEM_ID2)) {
+ tlan_mii_read_reg(dev, phy, MII_AN_LPA,
+ &partner);
+ tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR,
+ &tlphy_par);
+
+ netdev_info(dev,
+ "Link active, %s %uMbps %s-Duplex\n",
+ !(tlphy_par & TLAN_PHY_AN_EN_STAT)
+ ? "forced" : "Autonegotiation enabled,",
+ tlphy_par & TLAN_PHY_SPEED_100
+ ? 100 : 10,
+ tlphy_par & TLAN_PHY_DUPLEX_FULL
+ ? "Full" : "Half");
+
+ if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
+ netdev_info(dev, "Partner capability:");
+ for (i = 5; i < 10; i++)
+ if (partner & (1 << i))
+ pr_cont(" %s",
+ media[i-5]);
+ pr_cont("\n");
+ }
+ } else
+ netdev_info(dev, "Link active\n");
+ /* Enabling link beat monitoring */
+ priv->media_timer.function = tlan_phy_monitor;
+ priv->media_timer.data = (unsigned long) dev;
+ priv->media_timer.expires = jiffies + HZ;
+ add_timer(&priv->media_timer);
}
}
@@ -2312,6 +2345,7 @@ tlan_finish_reset(struct net_device *dev)
dev->base_addr + TLAN_HOST_CMD + 1);
outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM);
outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD);
+ tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK);
netif_carrier_on(dev);
} else {
netdev_info(dev, "Link inactive, will retry in 10 secs...\n");
@@ -2494,9 +2528,10 @@ static void tlan_phy_power_down(struct net_device *dev)
value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
tlan_mii_sync(dev->base_addr);
tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
- if ((priv->phy_num == 0) &&
- (priv->phy[1] != TLAN_PHY_NONE) &&
- (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) {
+ if ((priv->phy_num == 0) && (priv->phy[1] != TLAN_PHY_NONE)) {
+ /* if using internal PHY, the external PHY must be powered on */
+ if (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10)
+ value = MII_GC_ISOLATE; /* just isolate it from MII */
tlan_mii_sync(dev->base_addr);
tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value);
}
@@ -2538,6 +2573,7 @@ static void tlan_phy_reset(struct net_device *dev)
struct tlan_priv *priv = netdev_priv(dev);
u16 phy;
u16 value;
+ unsigned long timeout = jiffies + HZ;
phy = priv->phy[priv->phy_num];
@@ -2545,9 +2581,13 @@ static void tlan_phy_reset(struct net_device *dev)
tlan_mii_sync(dev->base_addr);
value = MII_GC_LOOPBK | MII_GC_RESET;
tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value);
- tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
- while (value & MII_GC_RESET)
+ do {
tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
+ if (time_after(jiffies, timeout)) {
+ netdev_err(dev, "PHY reset timeout\n");
+ return;
+ }
+ } while (value & MII_GC_RESET);
/* Wait for 500 ms and initialize.
* I don't remember why I wait this long.
@@ -2653,7 +2693,6 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
struct tlan_priv *priv = netdev_priv(dev);
u16 an_adv;
u16 an_lpa;
- u16 data;
u16 mode;
u16 phy;
u16 status;
@@ -2668,13 +2707,7 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
/* Wait for 8 sec to give the process
* more time. Perhaps we should fail after a while.
*/
- if (!priv->neg_be_verbose++) {
- pr_info("Giving autonegotiation more time.\n");
- pr_info("Please check that your adapter has\n");
- pr_info("been properly connected to a HUB or Switch.\n");
- pr_info("Trying to establish link in the background...\n");
- }
- tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN);
+ tlan_set_timer(dev, 2 * HZ, TLAN_TIMER_PHY_FINISH_AN);
return;
}
@@ -2687,13 +2720,11 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
else if (!(mode & 0x0080) && (mode & 0x0040))
priv->tlan_full_duplex = true;
+ /* switch to internal PHY for 10 Mbps */
if ((!(mode & 0x0180)) &&
(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) &&
(priv->phy_num != 0)) {
priv->phy_num = 0;
- data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
- | TLAN_NET_CFG_PHY_EN;
- tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN);
return;
}
@@ -2717,7 +2748,6 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
}
-#ifdef MONITOR
/*********************************************************************
*
@@ -2727,18 +2757,18 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
* None
*
* Params:
- * dev The device structure of this device.
+ * data The device structure of this device.
*
*
* This function monitors PHY condition by reading the status
- * register via the MII bus. This can be used to give info
- * about link changes (up/down), and possible switch to alternate
- * media.
+ * register via the MII bus, controls LINK LED and notifies the
+ * kernel about link state.
*
*******************************************************************/
-void tlan_phy_monitor(struct net_device *dev)
+static void tlan_phy_monitor(unsigned long data)
{
+ struct net_device *dev = (struct net_device *) data;
struct tlan_priv *priv = netdev_priv(dev);
u16 phy;
u16 phy_status;
@@ -2750,30 +2780,40 @@ void tlan_phy_monitor(struct net_device *dev)
/* Check if link has been lost */
if (!(phy_status & MII_GS_LINK)) {
- if (priv->link) {
- priv->link = 0;
+ if (netif_carrier_ok(dev)) {
printk(KERN_DEBUG "TLAN: %s has lost link\n",
dev->name);
+ tlan_dio_write8(dev->base_addr, TLAN_LED_REG, 0);
netif_carrier_off(dev);
- tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
- return;
+ if (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) {
+ /* power down internal PHY */
+ u16 data = MII_GC_PDOWN | MII_GC_LOOPBK |
+ MII_GC_ISOLATE;
+
+ tlan_mii_sync(dev->base_addr);
+ tlan_mii_write_reg(dev, priv->phy[0],
+ MII_GEN_CTL, data);
+ /* set to external PHY */
+ priv->phy_num = 1;
+ /* restart autonegotiation */
+ tlan_set_timer(dev, 4 * HZ / 10,
+ TLAN_TIMER_PHY_PDOWN);
+ return;
+ }
}
}
/* Link restablished? */
- if ((phy_status & MII_GS_LINK) && !priv->link) {
- priv->link = 1;
+ if ((phy_status & MII_GS_LINK) && !netif_carrier_ok(dev)) {
+ tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK);
printk(KERN_DEBUG "TLAN: %s has reestablished link\n",
dev->name);
netif_carrier_on(dev);
}
-
- /* Setup a new monitor */
- tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
+ priv->media_timer.expires = jiffies + HZ;
+ add_timer(&priv->media_timer);
}
-#endif /* MONITOR */
-
/*****************************************************************************
******************************************************************************
diff --git a/drivers/net/ethernet/ti/tlan.h b/drivers/net/ethernet/ti/tlan.h
index 2eb33a250788..e9928411827e 100644
--- a/drivers/net/ethernet/ti/tlan.h
+++ b/drivers/net/ethernet/ti/tlan.h
@@ -195,6 +195,7 @@ struct tlan_priv {
u32 timer_set_at;
u32 timer_type;
struct timer_list timer;
+ struct timer_list media_timer;
struct board *adapter;
u32 adapter_rev;
u32 aui;
@@ -206,9 +207,7 @@ struct tlan_priv {
u8 tlan_rev;
u8 tlan_full_duplex;
spinlock_t lock;
- u8 link;
struct work_struct tlan_tqueue;
- u8 neg_be_verbose;
};
@@ -219,7 +218,6 @@ struct tlan_priv {
*
****************************************************************/
-#define TLAN_TIMER_LINK_BEAT 1
#define TLAN_TIMER_ACTIVITY 2
#define TLAN_TIMER_PHY_PDOWN 3
#define TLAN_TIMER_PHY_PUP 4
@@ -241,6 +239,7 @@ struct tlan_priv {
#define TLAN_EEPROM_ACK 0
#define TLAN_EEPROM_STOP 1
+#define TLAN_EEPROM_SIZE 256