mv643xx_eth: print message on link status change
When there is a link status change (link or phy status interrupt), print a message notifying the user of the new link status. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
This commit is contained in:
parent
81600eea98
commit
2f7eb47a7b
|
@ -91,6 +91,12 @@ static char mv643xx_eth_driver_version[] = "1.1";
|
||||||
#define PORT_STATUS(p) (0x0444 + ((p) << 10))
|
#define PORT_STATUS(p) (0x0444 + ((p) << 10))
|
||||||
#define TX_FIFO_EMPTY 0x00000400
|
#define TX_FIFO_EMPTY 0x00000400
|
||||||
#define TX_IN_PROGRESS 0x00000080
|
#define TX_IN_PROGRESS 0x00000080
|
||||||
|
#define PORT_SPEED_MASK 0x00000030
|
||||||
|
#define PORT_SPEED_1000 0x00000010
|
||||||
|
#define PORT_SPEED_100 0x00000020
|
||||||
|
#define PORT_SPEED_10 0x00000000
|
||||||
|
#define FLOW_CONTROL_ENABLED 0x00000008
|
||||||
|
#define FULL_DUPLEX 0x00000004
|
||||||
#define LINK_UP 0x00000002
|
#define LINK_UP 0x00000002
|
||||||
#define TXQ_COMMAND(p) (0x0448 + ((p) << 10))
|
#define TXQ_COMMAND(p) (0x0448 + ((p) << 10))
|
||||||
#define TXQ_FIX_PRIO_CONF(p) (0x044c + ((p) << 10))
|
#define TXQ_FIX_PRIO_CONF(p) (0x044c + ((p) << 10))
|
||||||
|
@ -1679,6 +1685,64 @@ static void txq_deinit(struct tx_queue *txq)
|
||||||
|
|
||||||
|
|
||||||
/* netdev ops and related ***************************************************/
|
/* netdev ops and related ***************************************************/
|
||||||
|
static void handle_link_event(struct mv643xx_eth_private *mp)
|
||||||
|
{
|
||||||
|
struct net_device *dev = mp->dev;
|
||||||
|
u32 port_status;
|
||||||
|
int speed;
|
||||||
|
int duplex;
|
||||||
|
int fc;
|
||||||
|
|
||||||
|
port_status = rdl(mp, PORT_STATUS(mp->port_num));
|
||||||
|
if (!(port_status & LINK_UP)) {
|
||||||
|
if (netif_carrier_ok(dev)) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printk(KERN_INFO "%s: link down\n", dev->name);
|
||||||
|
|
||||||
|
netif_carrier_off(dev);
|
||||||
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
struct tx_queue *txq = mp->txq + i;
|
||||||
|
|
||||||
|
if (mp->txq_mask & (1 << i)) {
|
||||||
|
txq_reclaim(txq, 1);
|
||||||
|
txq_reset_hw_ptr(txq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (port_status & PORT_SPEED_MASK) {
|
||||||
|
case PORT_SPEED_10:
|
||||||
|
speed = 10;
|
||||||
|
break;
|
||||||
|
case PORT_SPEED_100:
|
||||||
|
speed = 100;
|
||||||
|
break;
|
||||||
|
case PORT_SPEED_1000:
|
||||||
|
speed = 1000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
speed = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
duplex = (port_status & FULL_DUPLEX) ? 1 : 0;
|
||||||
|
fc = (port_status & FLOW_CONTROL_ENABLED) ? 1 : 0;
|
||||||
|
|
||||||
|
printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
|
||||||
|
"flow control %sabled\n", dev->name,
|
||||||
|
speed, duplex ? "full" : "half",
|
||||||
|
fc ? "en" : "dis");
|
||||||
|
|
||||||
|
if (!netif_carrier_ok(dev)) {
|
||||||
|
netif_carrier_on(dev);
|
||||||
|
netif_wake_queue(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
|
static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct net_device *dev = (struct net_device *)dev_id;
|
struct net_device *dev = (struct net_device *)dev_id;
|
||||||
|
@ -1698,28 +1762,8 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
|
||||||
wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext);
|
wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) {
|
if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK))
|
||||||
if (rdl(mp, PORT_STATUS(mp->port_num)) & LINK_UP) {
|
handle_link_event(mp);
|
||||||
if (!netif_carrier_ok(dev)) {
|
|
||||||
netif_carrier_on(dev);
|
|
||||||
netif_wake_queue(dev);
|
|
||||||
}
|
|
||||||
} else if (netif_carrier_ok(dev)) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
netif_stop_queue(dev);
|
|
||||||
netif_carrier_off(dev);
|
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
struct tx_queue *txq = mp->txq + i;
|
|
||||||
|
|
||||||
if (mp->txq_mask & (1 << i)) {
|
|
||||||
txq_reclaim(txq, 1);
|
|
||||||
txq_reset_hw_ptr(txq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RxBuffer or RxError set for any of the 8 queues?
|
* RxBuffer or RxError set for any of the 8 queues?
|
||||||
|
@ -1970,6 +2014,9 @@ static int mv643xx_eth_open(struct net_device *dev)
|
||||||
napi_enable(&mp->napi);
|
napi_enable(&mp->napi);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
netif_carrier_off(dev);
|
||||||
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
port_start(mp);
|
port_start(mp);
|
||||||
|
|
||||||
set_rx_coal(mp, 0);
|
set_rx_coal(mp, 0);
|
||||||
|
|
Reference in New Issue