diff options
-rw-r--r-- | 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 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 | ||
1627 | propagate_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: |