aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/net/Kconfig1
-rw-r--r--drivers/net/tg3.c128
-rw-r--r--drivers/net/tg3.h5
3 files changed, 127 insertions, 7 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9f6cc8a56073..78cc9495fd46 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2228,6 +2228,7 @@ config VIA_VELOCITY
2228config TIGON3 2228config TIGON3
2229 tristate "Broadcom Tigon3 support" 2229 tristate "Broadcom Tigon3 support"
2230 depends on PCI 2230 depends on PCI
2231 select PHYLIB
2231 help 2232 help
2232 This driver supports Broadcom Tigon3 based gigabit Ethernet cards. 2233 This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
2233 2234
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);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index a3598ed9f5fc..e0914fdaf274 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2481,6 +2481,8 @@ struct tg3 {
2481#define TG3_FLG3_5761_5784_AX_FIXES 0x00000004 2481#define TG3_FLG3_5761_5784_AX_FIXES 0x00000004
2482#define TG3_FLG3_5701_DMA_BUG 0x00000008 2482#define TG3_FLG3_5701_DMA_BUG 0x00000008
2483#define TG3_FLG3_USE_PHYLIB 0x00000010 2483#define TG3_FLG3_USE_PHYLIB 0x00000010
2484#define TG3_FLG3_MDIOBUS_INITED 0x00000020
2485#define TG3_FLG3_MDIOBUS_PAUSED 0x00000040
2484 2486
2485 struct timer_list timer; 2487 struct timer_list timer;
2486 u16 timer_counter; 2488 u16 timer_counter;
@@ -2521,6 +2523,9 @@ struct tg3 {
2521 int msi_cap; 2523 int msi_cap;
2522 int pcix_cap; 2524 int pcix_cap;
2523 2525
2526 struct mii_bus mdio_bus;
2527 int mdio_irq[PHY_MAX_ADDR];
2528
2524 /* PHY info */ 2529 /* PHY info */
2525 u32 phy_id; 2530 u32 phy_id;
2526#define PHY_ID_MASK 0xfffffff0 2531#define PHY_ID_MASK 0xfffffff0