]> err.no Git - linux-2.6/blobdiff - drivers/net/tg3.c
bnx2: Allow flexible VLAN tag settings.
[linux-2.6] / drivers / net / tg3.c
index 69ded90cd96eb961765eb6f0c70518ea22daec54..633c128a622868ac91b9cde33b41baf6c4e8e219 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
+#include <linux/brcmphy.h>
 #include <linux/if_vlan.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
@@ -65,8 +66,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.92"
-#define DRV_MODULE_RELDATE     "May 2, 2008"
+#define DRV_MODULE_VERSION     "3.93"
+#define DRV_MODULE_RELDATE     "May 22, 2008"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -869,6 +870,51 @@ static int tg3_mdio_reset(struct mii_bus *bp)
        return 0;
 }
 
+static void tg3_mdio_config(struct tg3 *tp)
+{
+       u32 val;
+
+       if (tp->mdio_bus.phy_map[PHY_ADDR]->interface !=
+           PHY_INTERFACE_MODE_RGMII)
+               return;
+
+       val = tr32(MAC_PHYCFG1) & ~(MAC_PHYCFG1_RGMII_EXT_RX_DEC |
+                                   MAC_PHYCFG1_RGMII_SND_STAT_EN);
+       if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) {
+               if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+                       val |= MAC_PHYCFG1_RGMII_EXT_RX_DEC;
+               if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+                       val |= MAC_PHYCFG1_RGMII_SND_STAT_EN;
+       }
+       tw32(MAC_PHYCFG1, val | MAC_PHYCFG1_RGMII_INT | MAC_PHYCFG1_TXC_DRV);
+
+       val = tr32(MAC_PHYCFG2) & ~(MAC_PHYCFG2_INBAND_ENABLE);
+       if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE))
+               val |= MAC_PHYCFG2_INBAND_ENABLE;
+       tw32(MAC_PHYCFG2, val);
+
+       val = tr32(MAC_EXT_RGMII_MODE);
+       val &= ~(MAC_RGMII_MODE_RX_INT_B |
+                MAC_RGMII_MODE_RX_QUALITY |
+                MAC_RGMII_MODE_RX_ACTIVITY |
+                MAC_RGMII_MODE_RX_ENG_DET |
+                MAC_RGMII_MODE_TX_ENABLE |
+                MAC_RGMII_MODE_TX_LOWPWR |
+                MAC_RGMII_MODE_TX_RESET);
+       if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) {
+               if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+                       val |= MAC_RGMII_MODE_RX_INT_B |
+                              MAC_RGMII_MODE_RX_QUALITY |
+                              MAC_RGMII_MODE_RX_ACTIVITY |
+                              MAC_RGMII_MODE_RX_ENG_DET;
+               if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+                       val |= MAC_RGMII_MODE_TX_ENABLE |
+                              MAC_RGMII_MODE_TX_LOWPWR |
+                              MAC_RGMII_MODE_TX_RESET;
+       }
+       tw32(MAC_EXT_RGMII_MODE, val);
+}
+
 static void tg3_mdio_start(struct tg3 *tp)
 {
        if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
@@ -880,6 +926,9 @@ static void tg3_mdio_start(struct tg3 *tp)
        tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
        tw32_f(MAC_MI_MODE, tp->mi_mode);
        udelay(80);
+
+       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED)
+               tg3_mdio_config(tp);
 }
 
 static void tg3_mdio_stop(struct tg3 *tp)
@@ -895,6 +944,7 @@ static int tg3_mdio_init(struct tg3 *tp)
 {
        int i;
        u32 reg;
+       struct phy_device *phydev;
        struct mii_bus *mdio_bus = &tp->mdio_bus;
 
        tg3_mdio_start(tp);
@@ -928,13 +978,34 @@ static int tg3_mdio_init(struct tg3 *tp)
                tg3_bmcr_reset(tp);
 
        i = mdiobus_register(mdio_bus);
-       if (!i)
-               tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
-       else
+       if (i) {
                printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n",
                        tp->dev->name, i);
+               return i;
+       }
+
+       tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
 
-       return i;
+       phydev = tp->mdio_bus.phy_map[PHY_ADDR];
+
+       switch (phydev->phy_id) {
+       case TG3_PHY_ID_BCM50610:
+               phydev->interface = PHY_INTERFACE_MODE_RGMII;
+               if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)
+                       phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
+               if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+                       phydev->dev_flags |= PHY_BRCM_EXT_IBND_RX_ENABLE;
+               if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+                       phydev->dev_flags |= PHY_BRCM_EXT_IBND_TX_ENABLE;
+               break;
+       case TG3_PHY_ID_BCMAC131:
+               phydev->interface = PHY_INTERFACE_MODE_MII;
+               break;
+       }
+
+       tg3_mdio_config(tp);
+
+       return 0;
 }
 
 static void tg3_mdio_fini(struct tg3 *tp)
@@ -1238,8 +1309,8 @@ static int tg3_phy_init(struct tg3 *tp)
        phydev = tp->mdio_bus.phy_map[PHY_ADDR];
 
        /* Attach the MAC to the PHY. */
-       phydev = phy_connect(tp->dev, phydev->dev.bus_id,
-                            tg3_adjust_link, 0, phydev->interface);
+       phydev = phy_connect(tp->dev, phydev->dev.bus_id, tg3_adjust_link,
+                            phydev->dev_flags, phydev->interface);
        if (IS_ERR(phydev)) {
                printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name);
                return PTR_ERR(phydev);
@@ -1757,6 +1828,21 @@ static void tg3_frob_aux_power(struct tg3 *tp)
                                     GRC_LCLCTRL_GPIO_OUTPUT0 |
                                     GRC_LCLCTRL_GPIO_OUTPUT1),
                                    100);
+               } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+                       /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */
+                       u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
+                                            GRC_LCLCTRL_GPIO_OE1 |
+                                            GRC_LCLCTRL_GPIO_OE2 |
+                                            GRC_LCLCTRL_GPIO_OUTPUT0 |
+                                            GRC_LCLCTRL_GPIO_OUTPUT1 |
+                                            tp->grc_local_ctrl;
+                       tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100);
+
+                       grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2;
+                       tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100);
+
+                       grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0;
+                       tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100);
                } else {
                        u32 no_gpio2;
                        u32 grc_local_ctrl = 0;
@@ -1942,7 +2028,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                       "requested.\n",
                       tp->dev->name, state);
                return -EINVAL;
-       };
+       }
 
        power_control |= PCI_PM_CTRL_PME_ENABLE;
 
@@ -2201,7 +2287,7 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8
                *speed = SPEED_INVALID;
                *duplex = DUPLEX_INVALID;
                break;
-       };
+       }
 }
 
 static void tg3_phy_copper_begin(struct tg3 *tp)
@@ -2313,7 +2399,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
                case SPEED_1000:
                        bmcr |= TG3_BMCR_SPEED1000;
                        break;
-               };
+               }
 
                if (tp->link_config.duplex == DUPLEX_FULL)
                        bmcr |= BMCR_FULLDPLX;
@@ -3011,7 +3097,7 @@ static int tg3_fiber_aneg_smachine(struct tg3 *tp,
        default:
                ret = ANEG_FAILED;
                break;
-       };
+       }
 
        return ret;
 }
@@ -3463,8 +3549,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
        err |= tg3_readphy(tp, MII_BMCR, &bmcr);
 
        if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset &&
-           (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) &&
-            tp->link_config.flowctrl == tp->link_config.active_flowctrl) {
+           (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) {
                /* do nothing, just check for link up at the end */
        } else if (tp->link_config.autoneg == AUTONEG_ENABLE) {
                u32 adv, new_adv;
@@ -3853,7 +3938,7 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
 
        default:
                return -EINVAL;
-       };
+       }
 
        /* Do not overwrite any of the map or rp information
         * until we are sure we can commit to a new buffer.
@@ -3913,7 +3998,7 @@ static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
 
        default:
                return;
-       };
+       }
 
        dest_map->skb = src_map->skb;
        pci_unmap_addr_set(dest_map, mapping,
@@ -5276,7 +5361,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int
 
                default:
                        break;
-               };
+               }
        }
 
        val = tr32(ofs);
@@ -5518,7 +5603,7 @@ static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind)
 
                default:
                        break;
-               };
+               }
        }
 
        if (kind == RESET_KIND_INIT ||
@@ -5543,7 +5628,7 @@ static void tg3_write_sig_post_reset(struct tg3 *tp, int kind)
 
                default:
                        break;
-               };
+               }
        }
 
        if (kind == RESET_KIND_SHUTDOWN)
@@ -5572,7 +5657,7 @@ static void tg3_write_sig_legacy(struct tg3 *tp, int kind)
 
                default:
                        break;
-               };
+               }
        }
 }
 
@@ -7606,7 +7691,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 
        default:
                break;
-       };
+       }
 
        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
                /* Write our heartbeat update interval to APE. */
@@ -8937,7 +9022,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                   (cmd->speed == SPEED_1000))
                return -EINVAL;
        else if ((cmd->speed == SPEED_1000) &&
-                (tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+                (tp->tg3_flags & TG3_FLAG_10_100_ONLY))
                return -EINVAL;
 
        tg3_full_lock(tp, 0);
@@ -11219,7 +11304,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
        tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
        if (val == NIC_SRAM_DATA_SIG_MAGIC) {
                u32 nic_cfg, led_cfg;
-               u32 nic_phy_id, ver, cfg2 = 0, eeprom_phy_id;
+               u32 nic_phy_id, ver, cfg2 = 0, cfg4 = 0, eeprom_phy_id;
                int eeprom_phy_serdes = 0;
 
                tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
@@ -11233,6 +11318,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                    (ver > 0) && (ver < 0x100))
                        tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2);
 
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+                       tg3_read_mem(tp, NIC_SRAM_DATA_CFG_4, &cfg4);
+
                if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) ==
                    NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER)
                        eeprom_phy_serdes = 1;
@@ -11305,7 +11393,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                                                 LED_CTRL_MODE_PHY_2);
                        break;
 
-               };
+               }
 
                if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
                     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) &&
@@ -11357,6 +11445,13 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                        if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE)
                                tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
                }
+
+               if (cfg4 & NIC_SRAM_RGMII_STD_IBND_DISABLE)
+                       tp->tg3_flags3 |= TG3_FLG3_RGMII_STD_IBND_DISABLE;
+               if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_RX_EN)
+                       tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_RX_EN;
+               if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN)
+                       tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_TX_EN;
        }
 }
 
@@ -12194,6 +12289,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
 
+       if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+               /* Turn off the debug UART. */
+               tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
+               if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
+                       /* Keep VMain power. */
+                       tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 |
+                                             GRC_LCLCTRL_GPIO_OUTPUT0;
+       }
+
        /* Force the chip into D0. */
        err = tg3_set_power_state(tp, PCI_D0);
        if (err) {
@@ -12609,7 +12713,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
                        val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX |
                                DMA_RWCTRL_WRITE_BNDRY_384_PCIX);
                        break;
-               };
+               }
        } else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
                switch (cacheline_size) {
                case 16:
@@ -12626,7 +12730,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
                        val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE;
                        val |= DMA_RWCTRL_WRITE_BNDRY_128_PCIE;
                        break;
-               };
+               }
        } else {
                switch (cacheline_size) {
                case 16:
@@ -12670,7 +12774,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
                        val |= (DMA_RWCTRL_READ_BNDRY_1024 |
                                DMA_RWCTRL_WRITE_BNDRY_1024);
                        break;
-               };
+               }
        }
 
 out:
@@ -13030,7 +13134,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
        case PHY_ID_BCM8002:    return "8002/serdes";
        case 0:                 return "serdes";
        default:                return "unknown";
-       };
+       }
 }
 
 static char * __devinit tg3_bus_string(struct tg3 *tp, char *str)