Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=68c90166e4aaa15ddcdd4778ad30bfb8b32534be
Commit:     68c90166e4aaa15ddcdd4778ad30bfb8b32534be
Parent:     208491d8f92e5aa129acb27e223e75d0173a3edd
Author:     Mark Brown <[EMAIL PROTECTED]>
AuthorDate: Mon Feb 19 20:15:39 2007 +0000
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Tue Feb 20 11:18:13 2007 -0500

    natsemi: Add support for using MII port with no PHY
    
    This patch provides code paths which allow the natsemi driver to use the
    external MII port on the chip but ignore any PHYs that may be attached to 
it.
    The link state will be left as it was when the driver started and can be
    configured via ethtool.  Any PHYs that are present can be accessed via the 
MII
    ioctl()s.
    
    This is useful for systems where the device is connected without a PHY
    or where either information or actions outside the scope of the driver
    are required in order to use the PHYs.
    
    Signed-Off-By: Mark Brown <[EMAIL PROTECTED]>
    
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/net/natsemi.c |   35 ++++++++++++++++++++++++++++++-----
 1 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index ffa0afd..4e21f55 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -568,6 +568,8 @@ struct netdev_private {
        u32 intr_status;
        /* Do not touch the nic registers */
        int hands_off;
+       /* Don't pay attention to the reported link state. */
+       int ignore_phy;
        /* external phy that is used: only valid if dev->if_port != PORT_TP */
        int mii;
        int phy_addr_external;
@@ -696,7 +698,10 @@ static void __devinit natsemi_init_media (struct 
net_device *dev)
        struct netdev_private *np = netdev_priv(dev);
        u32 tmp;
 
-       netif_carrier_off(dev);
+       if (np->ignore_phy)
+               netif_carrier_on(dev);
+       else
+               netif_carrier_off(dev);
 
        /* get the initial settings from hardware */
        tmp            = mdio_read(dev, MII_BMCR);
@@ -806,8 +811,10 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
        np->hands_off = 0;
        np->intr_status = 0;
        np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size;
+       np->ignore_phy = 0;
 
        /* Initial port:
+        * - If configured to ignore the PHY set up for external.
         * - If the nic was configured to use an external phy and if find_mii
         *   finds a phy: use external port, first phy that replies.
         * - Otherwise: internal port.
@@ -815,7 +822,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
         * The address would be used to access a phy over the mii bus, but
         * the internal phy is accessed through mapped registers.
         */
-       if (readl(ioaddr + ChipConfig) & CfgExtPhy)
+       if (np->ignore_phy || readl(ioaddr + ChipConfig) & CfgExtPhy)
                dev->if_port = PORT_MII;
        else
                dev->if_port = PORT_TP;
@@ -825,7 +832,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 
        if (dev->if_port != PORT_TP) {
                np->phy_addr_external = find_mii(dev);
-               if (np->phy_addr_external == PHY_ADDR_NONE) {
+               /* If we're ignoring the PHY it doesn't matter if we can't
+                * find one. */
+               if (!np->ignore_phy && np->phy_addr_external == PHY_ADDR_NONE) {
                        dev->if_port = PORT_TP;
                        np->phy_addr_external = PHY_ADDR_INTERNAL;
                }
@@ -891,6 +900,8 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
                printk("%02x, IRQ %d", dev->dev_addr[i], irq);
                if (dev->if_port == PORT_TP)
                        printk(", port TP.\n");
+               else if (np->ignore_phy)
+                       printk(", port MII, ignoring PHY\n");
                else
                        printk(", port MII, phy ad %d.\n", 
np->phy_addr_external);
        }
@@ -1571,9 +1582,13 @@ static void check_link(struct net_device *dev)
 {
        struct netdev_private *np = netdev_priv(dev);
        void __iomem * ioaddr = ns_ioaddr(dev);
-       int duplex;
+       int duplex = np->duplex;
        u16 bmsr;
 
+       /* If we are ignoring the PHY then don't try reading it. */
+       if (np->ignore_phy)
+               goto propagate_state;
+
        /* The link status field is latched: it remains low after a temporary
         * link failure until it's read. We need the current link status,
         * thus read twice.
@@ -1585,7 +1600,7 @@ static void check_link(struct net_device *dev)
                if (netif_carrier_ok(dev)) {
                        if (netif_msg_link(np))
                                printk(KERN_NOTICE "%s: link down.\n",
-                                       dev->name);
+                                      dev->name);
                        netif_carrier_off(dev);
                        undo_cable_magic(dev);
                }
@@ -1609,6 +1624,7 @@ static void check_link(struct net_device *dev)
                        duplex = 1;
        }
 
+propagate_state:
        /* if duplex is set then bit 28 must be set, too */
        if (duplex ^ !!(np->rx_config & RxAcceptTx)) {
                if (netif_msg_link(np))
@@ -2819,6 +2835,15 @@ static int netdev_set_ecmd(struct net_device *dev, 
struct ethtool_cmd *ecmd)
        }
 
        /*
+        * If we're ignoring the PHY then autoneg and the internal
+        * transciever are really not going to work so don't let the
+        * user select them.
+        */
+       if (np->ignore_phy && (ecmd->autoneg == AUTONEG_ENABLE ||
+                              ecmd->port == PORT_TP))
+               return -EINVAL;
+
+       /*
         * maxtxpkt, maxrxpkt: ignored for now.
         *
         * transceiver:
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to