Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Matt Carlson and committed by
David S. Miller
158d7abd dd477003

+127 -7
+1
drivers/net/Kconfig
··· 2228 2228 config TIGON3 2229 2229 tristate "Broadcom Tigon3 support" 2230 2230 depends on PCI 2231 + select PHYLIB 2231 2232 help 2232 2233 This driver supports Broadcom Tigon3 based gigabit Ethernet cards. 2233 2234
+121 -7
drivers/net/tg3.c
··· 32 32 #include <linux/skbuff.h> 33 33 #include <linux/ethtool.h> 34 34 #include <linux/mii.h> 35 + #include <linux/phy.h> 35 36 #include <linux/if_vlan.h> 36 37 #include <linux/ip.h> 37 38 #include <linux/tcp.h> ··· 834 833 return -EBUSY; 835 834 836 835 return 0; 836 + } 837 + 838 + static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg) 839 + { 840 + struct tg3 *tp = (struct tg3 *)bp->priv; 841 + u32 val; 842 + 843 + if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED) 844 + return -EAGAIN; 845 + 846 + if (tg3_readphy(tp, reg, &val)) 847 + return -EIO; 848 + 849 + return val; 850 + } 851 + 852 + static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val) 853 + { 854 + struct tg3 *tp = (struct tg3 *)bp->priv; 855 + 856 + if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED) 857 + return -EAGAIN; 858 + 859 + if (tg3_writephy(tp, reg, val)) 860 + return -EIO; 861 + 862 + return 0; 863 + } 864 + 865 + static int tg3_mdio_reset(struct mii_bus *bp) 866 + { 867 + return 0; 868 + } 869 + 870 + static void tg3_mdio_start(struct tg3 *tp) 871 + { 872 + if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) { 873 + mutex_lock(&tp->mdio_bus.mdio_lock); 874 + tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED; 875 + mutex_unlock(&tp->mdio_bus.mdio_lock); 876 + } 877 + 878 + tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL; 879 + tw32_f(MAC_MI_MODE, tp->mi_mode); 880 + udelay(80); 881 + } 882 + 883 + static void tg3_mdio_stop(struct tg3 *tp) 884 + { 885 + if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) { 886 + mutex_lock(&tp->mdio_bus.mdio_lock); 887 + tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED; 888 + mutex_unlock(&tp->mdio_bus.mdio_lock); 889 + } 890 + } 891 + 892 + static int tg3_mdio_init(struct tg3 *tp) 893 + { 894 + int i; 895 + u32 reg; 896 + struct mii_bus *mdio_bus = &tp->mdio_bus; 897 + 898 + tg3_mdio_start(tp); 899 + 900 + if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) || 901 + (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED)) 902 + return 0; 903 + 904 + memset(mdio_bus, 0, sizeof(*mdio_bus)); 905 + 906 + mdio_bus->name = "tg3 mdio bus"; 907 + snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%x", 908 + (tp->pdev->bus->number << 8) | tp->pdev->devfn); 909 + mdio_bus->priv = tp; 910 + mdio_bus->dev = &tp->pdev->dev; 911 + mdio_bus->read = &tg3_mdio_read; 912 + mdio_bus->write = &tg3_mdio_write; 913 + mdio_bus->reset = &tg3_mdio_reset; 914 + mdio_bus->phy_mask = ~(1 << PHY_ADDR); 915 + mdio_bus->irq = &tp->mdio_irq[0]; 916 + 917 + for (i = 0; i < PHY_MAX_ADDR; i++) 918 + mdio_bus->irq[i] = PHY_POLL; 919 + 920 + /* The bus registration will look for all the PHYs on the mdio bus. 921 + * Unfortunately, it does not ensure the PHY is powered up before 922 + * accessing the PHY ID registers. A chip reset is the 923 + * quickest way to bring the device back to an operational state.. 924 + */ 925 + if (tg3_readphy(tp, MII_BMCR, &reg) || (reg & BMCR_PDOWN)) 926 + tg3_bmcr_reset(tp); 927 + 928 + i = mdiobus_register(mdio_bus); 929 + if (!i) 930 + tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED; 931 + else 932 + printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n", 933 + tp->dev->name, i); 934 + 935 + return i; 936 + } 937 + 938 + static void tg3_mdio_fini(struct tg3 *tp) 939 + { 940 + if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) { 941 + tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED; 942 + mdiobus_unregister(&tp->mdio_bus); 943 + tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED; 944 + } 837 945 } 838 946 839 947 /* tp->lock is held. */ ··· 5496 5386 5497 5387 tg3_nvram_lock(tp); 5498 5388 5389 + tg3_mdio_stop(tp); 5390 + 5499 5391 /* No matching tg3_nvram_unlock() after this because 5500 5392 * chip reset below will undo the nvram lock. 5501 5393 */ ··· 5648 5536 } else 5649 5537 tw32_f(MAC_MODE, 0); 5650 5538 udelay(40); 5539 + 5540 + tg3_mdio_start(tp); 5651 5541 5652 5542 err = tg3_poll_fw(tp); 5653 5543 if (err) ··· 7281 7167 7282 7168 tw32_f(MAC_RX_MODE, tp->rx_mode); 7283 7169 udelay(10); 7284 - 7285 - tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL; 7286 - tw32_f(MAC_MI_MODE, tp->mi_mode); 7287 - udelay(80); 7288 7170 7289 7171 tw32(MAC_LED_CTRL, tp->led_ctrl); 7290 7172 ··· 11960 11850 GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX) 11961 11851 tp->coalesce_mode |= HOSTCC_MODE_32BYTE; 11962 11852 11963 - /* Initialize MAC MI mode, polling disabled. */ 11964 - tw32_f(MAC_MI_MODE, tp->mi_mode); 11965 - udelay(80); 11853 + err = tg3_mdio_init(tp); 11854 + if (err) 11855 + return err; 11966 11856 11967 11857 /* Initialize data/descriptor byte/word swapping. */ 11968 11858 val = tr32(GRC_MODE); ··· 13162 13052 struct tg3 *tp = netdev_priv(dev); 13163 13053 13164 13054 flush_scheduled_work(); 13055 + 13056 + if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) 13057 + tg3_mdio_fini(tp); 13058 + 13165 13059 unregister_netdev(dev); 13166 13060 if (tp->aperegs) { 13167 13061 iounmap(tp->aperegs);
+5
drivers/net/tg3.h
··· 2481 2481 #define TG3_FLG3_5761_5784_AX_FIXES 0x00000004 2482 2482 #define TG3_FLG3_5701_DMA_BUG 0x00000008 2483 2483 #define TG3_FLG3_USE_PHYLIB 0x00000010 2484 + #define TG3_FLG3_MDIOBUS_INITED 0x00000020 2485 + #define TG3_FLG3_MDIOBUS_PAUSED 0x00000040 2484 2486 2485 2487 struct timer_list timer; 2486 2488 u16 timer_counter; ··· 2522 2520 int pm_cap; 2523 2521 int msi_cap; 2524 2522 int pcix_cap; 2523 + 2524 + struct mii_bus mdio_bus; 2525 + int mdio_irq[PHY_MAX_ADDR]; 2525 2526 2526 2527 /* PHY info */ 2527 2528 u32 phy_id;