Loading drivers/net/mv643xx_eth.c +69 −22 Original line number Diff line number Diff line Loading @@ -91,6 +91,12 @@ static char mv643xx_eth_driver_version[] = "1.1"; #define PORT_STATUS(p) (0x0444 + ((p) << 10)) #define TX_FIFO_EMPTY 0x00000400 #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 TXQ_COMMAND(p) (0x0448 + ((p) << 10)) #define TXQ_FIX_PRIO_CONF(p) (0x044c + ((p) << 10)) Loading Loading @@ -1679,6 +1685,64 @@ static void txq_deinit(struct tx_queue *txq) /* 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) { struct net_device *dev = (struct net_device *)dev_id; Loading @@ -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); } if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) { if (rdl(mp, PORT_STATUS(mp->port_num)) & LINK_UP) { 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); } } } } if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) handle_link_event(mp); /* * RxBuffer or RxError set for any of the 8 queues? Loading Loading @@ -1970,6 +2014,9 @@ static int mv643xx_eth_open(struct net_device *dev) napi_enable(&mp->napi); #endif netif_carrier_off(dev); netif_stop_queue(dev); port_start(mp); set_rx_coal(mp, 0); Loading Loading
drivers/net/mv643xx_eth.c +69 −22 Original line number Diff line number Diff line Loading @@ -91,6 +91,12 @@ static char mv643xx_eth_driver_version[] = "1.1"; #define PORT_STATUS(p) (0x0444 + ((p) << 10)) #define TX_FIFO_EMPTY 0x00000400 #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 TXQ_COMMAND(p) (0x0448 + ((p) << 10)) #define TXQ_FIX_PRIO_CONF(p) (0x044c + ((p) << 10)) Loading Loading @@ -1679,6 +1685,64 @@ static void txq_deinit(struct tx_queue *txq) /* 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) { struct net_device *dev = (struct net_device *)dev_id; Loading @@ -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); } if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) { if (rdl(mp, PORT_STATUS(mp->port_num)) & LINK_UP) { 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); } } } } if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) handle_link_event(mp); /* * RxBuffer or RxError set for any of the 8 queues? Loading Loading @@ -1970,6 +2014,9 @@ static int mv643xx_eth_open(struct net_device *dev) napi_enable(&mp->napi); #endif netif_carrier_off(dev); netif_stop_queue(dev); port_start(mp); set_rx_coal(mp, 0); Loading