aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMark Brown <broonie@sirena.org.uk>2007-02-19 15:15:39 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-20 11:18:13 -0500
commit68c90166e4aaa15ddcdd4778ad30bfb8b32534be (patch)
tree950de3fe588307589610ab4bef8c61de58bd7eab /drivers
parent208491d8f92e5aa129acb27e223e75d0173a3edd (diff)
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 <broonie@sirena.org.uk> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/natsemi.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index ffa0afd2eddc..4e21f5510b90 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -568,6 +568,8 @@ struct netdev_private {
568 u32 intr_status; 568 u32 intr_status;
569 /* Do not touch the nic registers */ 569 /* Do not touch the nic registers */
570 int hands_off; 570 int hands_off;
571 /* Don't pay attention to the reported link state. */
572 int ignore_phy;
571 /* external phy that is used: only valid if dev->if_port != PORT_TP */ 573 /* external phy that is used: only valid if dev->if_port != PORT_TP */
572 int mii; 574 int mii;
573 int phy_addr_external; 575 int phy_addr_external;
@@ -696,7 +698,10 @@ static void __devinit natsemi_init_media (struct net_device *dev)
696 struct netdev_private *np = netdev_priv(dev); 698 struct netdev_private *np = netdev_priv(dev);
697 u32 tmp; 699 u32 tmp;
698 700
699 netif_carrier_off(dev); 701 if (np->ignore_phy)
702 netif_carrier_on(dev);
703 else
704 netif_carrier_off(dev);
700 705
701 /* get the initial settings from hardware */ 706 /* get the initial settings from hardware */
702 tmp = mdio_read(dev, MII_BMCR); 707 tmp = mdio_read(dev, MII_BMCR);
@@ -806,8 +811,10 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
806 np->hands_off = 0; 811 np->hands_off = 0;
807 np->intr_status = 0; 812 np->intr_status = 0;
808 np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size; 813 np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size;
814 np->ignore_phy = 0;
809 815
810 /* Initial port: 816 /* Initial port:
817 * - If configured to ignore the PHY set up for external.
811 * - If the nic was configured to use an external phy and if find_mii 818 * - If the nic was configured to use an external phy and if find_mii
812 * finds a phy: use external port, first phy that replies. 819 * finds a phy: use external port, first phy that replies.
813 * - Otherwise: internal port. 820 * - Otherwise: internal port.
@@ -815,7 +822,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
815 * The address would be used to access a phy over the mii bus, but 822 * The address would be used to access a phy over the mii bus, but
816 * the internal phy is accessed through mapped registers. 823 * the internal phy is accessed through mapped registers.
817 */ 824 */
818 if (readl(ioaddr + ChipConfig) & CfgExtPhy) 825 if (np->ignore_phy || readl(ioaddr + ChipConfig) & CfgExtPhy)
819 dev->if_port = PORT_MII; 826 dev->if_port = PORT_MII;
820 else 827 else
821 dev->if_port = PORT_TP; 828 dev->if_port = PORT_TP;
@@ -825,7 +832,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
825 832
826 if (dev->if_port != PORT_TP) { 833 if (dev->if_port != PORT_TP) {
827 np->phy_addr_external = find_mii(dev); 834 np->phy_addr_external = find_mii(dev);
828 if (np->phy_addr_external == PHY_ADDR_NONE) { 835 /* If we're ignoring the PHY it doesn't matter if we can't
836 * find one. */
837 if (!np->ignore_phy && np->phy_addr_external == PHY_ADDR_NONE) {
829 dev->if_port = PORT_TP; 838 dev->if_port = PORT_TP;
830 np->phy_addr_external = PHY_ADDR_INTERNAL; 839 np->phy_addr_external = PHY_ADDR_INTERNAL;
831 } 840 }
@@ -891,6 +900,8 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
891 printk("%02x, IRQ %d", dev->dev_addr[i], irq); 900 printk("%02x, IRQ %d", dev->dev_addr[i], irq);
892 if (dev->if_port == PORT_TP) 901 if (dev->if_port == PORT_TP)
893 printk(", port TP.\n"); 902 printk(", port TP.\n");
903 else if (np->ignore_phy)
904 printk(", port MII, ignoring PHY\n");
894 else 905 else
895 printk(", port MII, phy ad %d.\n", np->phy_addr_external); 906 printk(", port MII, phy ad %d.\n", np->phy_addr_external);
896 } 907 }
@@ -1571,9 +1582,13 @@ static void check_link(struct net_device *dev)
1571{ 1582{
1572 struct netdev_private *np = netdev_priv(dev); 1583 struct netdev_private *np = netdev_priv(dev);
1573 void __iomem * ioaddr = ns_ioaddr(dev); 1584 void __iomem * ioaddr = ns_ioaddr(dev);
1574 int duplex; 1585 int duplex = np->duplex;
1575 u16 bmsr; 1586 u16 bmsr;
1576 1587
1588 /* If we are ignoring the PHY then don't try reading it. */
1589 if (np->ignore_phy)
1590 goto propagate_state;
1591
1577 /* The link status field is latched: it remains low after a temporary 1592 /* The link status field is latched: it remains low after a temporary
1578 * link failure until it's read. We need the current link status, 1593 * link failure until it's read. We need the current link status,
1579 * thus read twice. 1594 * thus read twice.
@@ -1585,7 +1600,7 @@ static void check_link(struct net_device *dev)
1585 if (netif_carrier_ok(dev)) { 1600 if (netif_carrier_ok(dev)) {
1586 if (netif_msg_link(np)) 1601 if (netif_msg_link(np))
1587 printk(KERN_NOTICE "%s: link down.\n", 1602 printk(KERN_NOTICE "%s: link down.\n",
1588 dev->name); 1603 dev->name);
1589 netif_carrier_off(dev); 1604 netif_carrier_off(dev);
1590 undo_cable_magic(dev); 1605 undo_cable_magic(dev);
1591 } 1606 }
@@ -1609,6 +1624,7 @@ static void check_link(struct net_device *dev)
1609 duplex = 1; 1624 duplex = 1;
1610 } 1625 }
1611 1626
1627propagate_state:
1612 /* if duplex is set then bit 28 must be set, too */ 1628 /* if duplex is set then bit 28 must be set, too */
1613 if (duplex ^ !!(np->rx_config & RxAcceptTx)) { 1629 if (duplex ^ !!(np->rx_config & RxAcceptTx)) {
1614 if (netif_msg_link(np)) 1630 if (netif_msg_link(np))
@@ -2819,6 +2835,15 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
2819 } 2835 }
2820 2836
2821 /* 2837 /*
2838 * If we're ignoring the PHY then autoneg and the internal
2839 * transciever are really not going to work so don't let the
2840 * user select them.
2841 */
2842 if (np->ignore_phy && (ecmd->autoneg == AUTONEG_ENABLE ||
2843 ecmd->port == PORT_TP))
2844 return -EINVAL;
2845
2846 /*
2822 * maxtxpkt, maxrxpkt: ignored for now. 2847 * maxtxpkt, maxrxpkt: ignored for now.
2823 * 2848 *
2824 * transceiver: 2849 * transceiver: