8139cp: LinkChg support
Subsystems (3)
PATCH 1/1 8139cp: LinkChg support
Hi, This patch adds LinkChg support to the 8139cp ethernet driver. Patch against 2.5.36. Please consider pulling it from:
http://cscience.org/~felipewd/linux/patches-fwd/2.5/8139cp-linkchg.patch
Felipe
8139cp.c renamed from 8139cp.c.orig +27 -1
@@ -22,11 +22,11 @@ Wake-on-LAN support - Felipe Damasio <[email protected]> PCI suspend/resume - Felipe Damasio <[email protected]> + LinkChg interrupt - Felipe Damasio <[email protected]> TODO, in rough priority order: * Test Tx checksumming thoroughly * dev->tx_timeout - * LinkChg interrupt * Support forcing media type with a module parameter, like dl2k.c/sundance.c * Constants (module parms?) for Rx work limit
@@ -396,6 +396,8 @@static void __cp_set_rx_mode (struct net_device *dev);static void cp_tx (struct cp_private *cp);static void cp_clean_rings (struct cp_private *cp); +static int mdio_read (struct net_device *dev,int phy_id,int location); +static void mdio_write (struct net_device *dev,int phy_id,int location,int value);enum board_type { RTL8139Cp,
@@ -655,6 +657,24 @@ cp->rx_tail = rx_tail; } +static inline void cp_linkchg (struct net_device *dev) +{ +struct cp_private *cp = dev->priv; + +if (mii_link_ok (&cp->mii_if)) { +if (netif_msg_link (cp)) { +u16 bmcr =mdio_read (dev, cp->mii_if.phy_id,MII_BMCR ); + +printk (PFX "Link Changed: %dMbps, %s duplex\n" , + bmcr &BMCR_SPEED100 ?100 :10 , + bmcr &BMCR_FULLDPLX ?"full" :"half" + ); + } +netif_carrier_on (dev); + } +else netif_carrier_off (dev);/* Link is down */ +} +static void cp_interrupt (int irq,void *dev_instance,struct pt_regs *regs) {struct net_device *dev = dev_instance;
@@ -675,6 +695,8 @@cp_rx (cp);if (status & (TxOK | TxErr | TxEmpty | SWInt))cp_tx (cp); +if (status & LinkChg) +cp_linkchg (dev);cpw16_f (IntrStatus, status);
@@ -1190,6 +1212,9 @@if (rc) goto err_out_hw; +if (mii_link_ok (&cp->mii_if)) +netif_carrier_on (dev); +else netif_carrier_off (dev);netif_start_queue (dev);return 0 ;
@@ -1208,6 +1233,7 @@printk (KERN_DEBUG "%s: disabling interface\n" , dev->name);netif_stop_queue (dev); +netif_carrier_off (dev);cp_stop_hw (cp);free_irq (dev->irq, dev);cp_free_rings (cp);
ALTPATCH: 8139cp: LinkChg support
Felipe,
Here is the patch I just committed, instead of your patch. I wanted a more generic solution, that is easily pluggable into other drivers.
Please test and let me know if you find bugs, or want additions...
Jeff
drivers/net/8139cp.c +6 -1
@@ -22,11 +22,11 @@ Wake-on-LAN support - Felipe Damasio <[email protected]> PCI suspend/resume - Felipe Damasio <[email protected]> + LinkChg interrupt - Felipe Damasio <[email protected]> TODO, in rough priority order: * Test Tx checksumming thoroughly * dev->tx_timeout - * LinkChg interrupt * Support forcing media type with a module parameter, like dl2k.c/sundance.c * Constants (module parms?) for Rx work limit
@@ -677,6 +677,8 @@cp_rx (cp);if (status & (TxOK | TxErr | TxEmpty | SWInt))cp_tx (cp); +if (status & LinkChg) +mii_check_media (&cp->mii_if,netif_msg_link (cp));if (status & PciErr) {u16 pci_status;
@@ -1192,6 +1194,8 @@if (rc) goto err_out_hw; +netif_carrier_off (dev); +mii_check_media (&cp->mii_if,netif_msg_link (cp));netif_start_queue (dev);return 0 ;
@@ -1210,6 +1214,7 @@printk (KERN_DEBUG "%s: disabling interface\n" , dev->name);netif_stop_queue (dev); +netif_carrier_off (dev);spin_lock_irq (&cp->lock);cp_stop_hw (cp);
drivers/net/mii.c +72 -0
81 lines not on this page · raw message
include/linux/mii.h +6 -4
@@ -118,10 +118,12 @@struct ethtool_cmd ; -int mii_link_ok (struct mii_if_info *mii); -int mii_nway_restart (struct mii_if_info *mii); -int mii_ethtool_gset (struct mii_if_info *mii,struct ethtool_cmd *ecmd); -int mii_ethtool_sset (struct mii_if_info *mii,struct ethtool_cmd *ecmd); +extern int mii_link_ok (struct mii_if_info *mii); +extern int mii_nway_restart (struct mii_if_info *mii); +extern int mii_ethtool_gset (struct mii_if_info *mii,struct ethtool_cmd *ecmd); +extern int mii_ethtool_sset (struct mii_if_info *mii,struct ethtool_cmd *ecmd); +extern void mii_check_link (struct mii_if_info *mii); +extern unsigned int mii_check_media (struct mii_if_info *mii,unsigned int ok_to_print);/* This structure is used in all SIOCxMIIxxx ioctl calls */
Re: ALTPATCH: 8139cp: LinkChg support
Quoted 9 lines · Jeff Garzik
diff -Nru
a/drivers/net/mii.cb/drivers/net/mii.cdrivers/net/mii.c +2
-0@@ -170,6 +170,75 @@return r; } +void mii_check_link (struct mii_if_info *mii) +{
drivers/net/mii.c line 184
Quoted 10 lines
drivers/net/mii.c +10
-0+if (mii_link_ok (mii)) +netif_carrier_on (mii->dev); +else +netif_carrier_off (mii->dev); +} + +unsigned int mii_check_media (struct mii_if_info *mii,unsigned int ok_to_print) +{ +unsigned int old_carrier, new_carrier; +int advertise, lpa, media, duplex;
Shouldn't advertise and lpa be either "unsigned short" or u16?
Quoted 29 lines
drivers/net/mii.c +29
-0+ +/* if forced media, go no further */ +if (mii->duplex_lock) +return 0 ;/* duplex did not change */ + +/* check current and old link status */ + old_carrier =netif_carrier_ok (mii->dev) ?1 :0 ; + new_carrier = (unsigned int )mii_link_ok (mii); + +/* if carrier state did not change, this is a "bounce", +* just exit as everything is already set correctly +*/ +if (old_carrier == new_carrier) +return 0 ;/* duplex did not change */ + +/* no carrier, nothing much to do */ +if (!new_carrier) { +netif_carrier_off (mii->dev); +if (ok_to_print) +printk (KERN_INFO "%s: link down\n" , mii->dev->name); +return 0 ;/* duplex did not change */ + } + +/* +* we have carrier, see who's on the other end +*/ +netif_carrier_on (mii->dev); + +/* get MII advertise and LPA values */
drivers/net/mii.c line 223
Quoted 10 lines
drivers/net/mii.c +10
-0+if (mii->advertising) + advertise = mii->advertising; +else { + advertise = mii->mdio_read (mii->dev, mii->phy_id,MII_ADVERTISE ); + mii->advertising = advertise; + } + lpa = mii->mdio_read (mii->dev, mii->phy_id,MII_LPA ); + +/* figure out media and duplex from advertise and LPA values */ + media =mii_nway_result (lpa & advertise);
^^^^^^^^^^^^^^^^^^^^^^^
mii_nway_result returns a "unsigned int", so media also doesn't look
good.
drivers/net/mii.c line 224
Quoted 1 line
drivers/net/mii.c +1
-0+ duplex = (media & (ADVERTISE_100FULL |ADVERTISE_10FULL )) ?1 :0 ;
Or we could do duplex = (media & ADVERTISE_FULL) ? 1 : 0;
Felipe
Re: ALTPATCH: 8139cp: LinkChg support
Quoted 4 lines · Felipe W Damasio
drivers/net/mii.c line 184
Quoted 1 line
drivers/net/mii.c +1
-0+int advertise, lpa, media, duplex;Shouldn't advertise and lpa be either "unsigned short" or u16?
No, they don't need to be.
Quoted 9 lines
drivers/net/mii.c line 223
Quoted 4 lines
drivers/net/mii.c +4
-0+ lpa = mii->mdio_read (mii->dev, mii->phy_id,MII_LPA ); + +/* figure out media and duplex from advertise and LPA values */ + media =mii_nway_result (lpa & advertise);^^^^^^^^^^^^^^^^^^^^^^^
mii_nway_resultreturns a "unsigned int", so media also doesn't look
good.
mii_nway_result _really_ returns a small bitmapped value, so it doesn't matter.
Quoted 6 lines
drivers/net/mii.c line 224
Quoted 1 line
drivers/net/mii.c +1
-0+ duplex = (media & (ADVERTISE_100FULL |ADVERTISE_10FULL )) ?1 :0 ;Or we could do duplex = (media & ADVERTISE_FULL) ? 1 : 0;
True. I forgot about that constant...
Jeff