aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2008-05-29 04:37:54 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-29 04:37:54 -0400
commit158d7abdae85e9ac43d99780c372d79c119f7626 (patch)
tree8cca893ab0ab854217249ddeea49b1280ee0361a /drivers/net/tg3.c
parentdd47700310ff929b439223105364c9ee3db81511 (diff)
tg3: Add mdio bus registration
This patch introduces code to register and unregister the tg3 mdio bus with the system. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: Benjamin Li <benli@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r--drivers/net/tg3.c128
1 files changed, 121 insertions, 7 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 538232586ee5..ce04c64a8a6e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -32,6 +32,7 @@
32#include <linux/skbuff.h> 32#include <linux/skbuff.h>
33#include <linux/ethtool.h> 33#include <linux/ethtool.h>
34#include <linux/mii.h> 34#include <linux/mii.h>
35#include <linux/phy.h>
35#include <linux/if_vlan.h> 36#include <linux/if_vlan.h>
36#include <linux/ip.h> 37#include <linux/ip.h>
37#include <linux/tcp.h> 38#include <linux/tcp.h>
@@ -835,6 +836,115 @@ static int tg3_bmcr_reset(struct tg3 *tp)
835 return 0; 836 return 0;
836} 837}
837 838
839static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
840{
841 struct tg3 *tp = (struct tg3 *)bp->priv;
842 u32 val;
843
844 if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
845 return -EAGAIN;
846
847 if (tg3_readphy(tp, reg, &val))
848 return -EIO;
849
850 return val;
851}
852
853static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
854{
855 struct tg3 *tp = (struct tg3 *)bp->priv;
856
857 if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
858 return -EAGAIN;
859
860 if (tg3_writephy(tp, reg, val))
861 return -EIO;
862
863 return 0;
864}
865
866static int tg3_mdio_reset(struct mii_bus *bp)
867{
868 return 0;
869}
870
871static void tg3_mdio_start(struct tg3 *tp)
872{
873 if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
874 mutex_lock(&tp->mdio_bus.mdio_lock);
875 tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
876 mutex_unlock(&tp->mdio_bus.mdio_lock);
877 }
878
879 tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
880 tw32_f(MAC_MI_MODE, tp->mi_mode);
881 udelay(80);
882}
883
884static void tg3_mdio_stop(struct tg3 *tp)
885{
886 if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
887 mutex_lock(&tp->mdio_bus.mdio_lock);
888 tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
889 mutex_unlock(&tp->mdio_bus.mdio_lock);
890 }
891}
892
893static int tg3_mdio_init(struct tg3 *tp)
894{
895 int i;
896 u32 reg;
897 struct mii_bus *mdio_bus = &tp->mdio_bus;
898
899 tg3_mdio_start(tp);
900
901 if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) ||
902 (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED))
903 return 0;
904
905 memset(mdio_bus, 0, sizeof(*mdio_bus));
906
907 mdio_bus->name = "tg3 mdio bus";
908 snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%x",
909 (tp->pdev->bus->number << 8) | tp->pdev->devfn);
910 mdio_bus->priv = tp;
911 mdio_bus->dev = &tp->pdev->dev;
912 mdio_bus->read = &tg3_mdio_read;
913 mdio_bus->write = &tg3_mdio_write;
914 mdio_bus->reset = &tg3_mdio_reset;
915 mdio_bus->phy_mask = ~(1 << PHY_ADDR);
916 mdio_bus->irq = &tp->mdio_irq[0];
917
918 for (i = 0; i < PHY_MAX_ADDR; i++)
919 mdio_bus->irq[i] = PHY_POLL;
920
921 /* The bus registration will look for all the PHYs on the mdio bus.
922 * Unfortunately, it does not ensure the PHY is powered up before
923 * accessing the PHY ID registers. A chip reset is the
924 * quickest way to bring the device back to an operational state..
925 */
926 if (tg3_readphy(tp, MII_BMCR, &reg) || (reg & BMCR_PDOWN))
927 tg3_bmcr_reset(tp);
928
929 i = mdiobus_register(mdio_bus);
930 if (!i)
931 tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
932 else
933 printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n",
934 tp->dev->name, i);
935
936 return i;
937}
938
939static void tg3_mdio_fini(struct tg3 *tp)
940{
941 if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
942 tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
943 mdiobus_unregister(&tp->mdio_bus);
944 tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
945 }
946}
947
838/* tp->lock is held. */ 948/* tp->lock is held. */
839static void tg3_wait_for_event_ack(struct tg3 *tp) 949static void tg3_wait_for_event_ack(struct tg3 *tp)
840{ 950{
@@ -5386,6 +5496,8 @@ static int tg3_chip_reset(struct tg3 *tp)
5386 5496
5387 tg3_nvram_lock(tp); 5497 tg3_nvram_lock(tp);
5388 5498
5499 tg3_mdio_stop(tp);
5500
5389 /* No matching tg3_nvram_unlock() after this because 5501 /* No matching tg3_nvram_unlock() after this because
5390 * chip reset below will undo the nvram lock. 5502 * chip reset below will undo the nvram lock.
5391 */ 5503 */
@@ -5537,6 +5649,8 @@ static int tg3_chip_reset(struct tg3 *tp)
5537 tw32_f(MAC_MODE, 0); 5649 tw32_f(MAC_MODE, 0);
5538 udelay(40); 5650 udelay(40);
5539 5651
5652 tg3_mdio_start(tp);
5653
5540 err = tg3_poll_fw(tp); 5654 err = tg3_poll_fw(tp);
5541 if (err) 5655 if (err)
5542 return err; 5656 return err;
@@ -7168,10 +7282,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
7168 tw32_f(MAC_RX_MODE, tp->rx_mode); 7282 tw32_f(MAC_RX_MODE, tp->rx_mode);
7169 udelay(10); 7283 udelay(10);
7170 7284
7171 tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
7172 tw32_f(MAC_MI_MODE, tp->mi_mode);
7173 udelay(80);
7174
7175 tw32(MAC_LED_CTRL, tp->led_ctrl); 7285 tw32(MAC_LED_CTRL, tp->led_ctrl);
7176 7286
7177 tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); 7287 tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
@@ -11850,9 +11960,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
11850 GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX) 11960 GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
11851 tp->coalesce_mode |= HOSTCC_MODE_32BYTE; 11961 tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
11852 11962
11853 /* Initialize MAC MI mode, polling disabled. */ 11963 err = tg3_mdio_init(tp);
11854 tw32_f(MAC_MI_MODE, tp->mi_mode); 11964 if (err)
11855 udelay(80); 11965 return err;
11856 11966
11857 /* Initialize data/descriptor byte/word swapping. */ 11967 /* Initialize data/descriptor byte/word swapping. */
11858 val = tr32(GRC_MODE); 11968 val = tr32(GRC_MODE);
@@ -13052,6 +13162,10 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
13052 struct tg3 *tp = netdev_priv(dev); 13162 struct tg3 *tp = netdev_priv(dev);
13053 13163
13054 flush_scheduled_work(); 13164 flush_scheduled_work();
13165
13166 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
13167 tg3_mdio_fini(tp);
13168
13055 unregister_netdev(dev); 13169 unregister_netdev(dev);
13056 if (tp->aperegs) { 13170 if (tp->aperegs) {
13057 iounmap(tp->aperegs); 13171 iounmap(tp->aperegs);