Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/e1000e/ich8lan.c
This commit is contained in:
@@ -1141,6 +1141,70 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static void gem_pcs_reset(struct gem *gp)
|
||||
{
|
||||
int limit;
|
||||
u32 val;
|
||||
|
||||
/* Reset PCS unit. */
|
||||
val = readl(gp->regs + PCS_MIICTRL);
|
||||
val |= PCS_MIICTRL_RST;
|
||||
writel(val, gp->regs + PCS_MIICTRL);
|
||||
|
||||
limit = 32;
|
||||
while (readl(gp->regs + PCS_MIICTRL) & PCS_MIICTRL_RST) {
|
||||
udelay(100);
|
||||
if (limit-- <= 0)
|
||||
break;
|
||||
}
|
||||
if (limit <= 0)
|
||||
printk(KERN_WARNING "%s: PCS reset bit would not clear.\n",
|
||||
gp->dev->name);
|
||||
}
|
||||
|
||||
static void gem_pcs_reinit_adv(struct gem *gp)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* Make sure PCS is disabled while changing advertisement
|
||||
* configuration.
|
||||
*/
|
||||
val = readl(gp->regs + PCS_CFG);
|
||||
val &= ~(PCS_CFG_ENABLE | PCS_CFG_TO);
|
||||
writel(val, gp->regs + PCS_CFG);
|
||||
|
||||
/* Advertise all capabilities except assymetric
|
||||
* pause.
|
||||
*/
|
||||
val = readl(gp->regs + PCS_MIIADV);
|
||||
val |= (PCS_MIIADV_FD | PCS_MIIADV_HD |
|
||||
PCS_MIIADV_SP | PCS_MIIADV_AP);
|
||||
writel(val, gp->regs + PCS_MIIADV);
|
||||
|
||||
/* Enable and restart auto-negotiation, disable wrapback/loopback,
|
||||
* and re-enable PCS.
|
||||
*/
|
||||
val = readl(gp->regs + PCS_MIICTRL);
|
||||
val |= (PCS_MIICTRL_RAN | PCS_MIICTRL_ANE);
|
||||
val &= ~PCS_MIICTRL_WB;
|
||||
writel(val, gp->regs + PCS_MIICTRL);
|
||||
|
||||
val = readl(gp->regs + PCS_CFG);
|
||||
val |= PCS_CFG_ENABLE;
|
||||
writel(val, gp->regs + PCS_CFG);
|
||||
|
||||
/* Make sure serialink loopback is off. The meaning
|
||||
* of this bit is logically inverted based upon whether
|
||||
* you are in Serialink or SERDES mode.
|
||||
*/
|
||||
val = readl(gp->regs + PCS_SCTRL);
|
||||
if (gp->phy_type == phy_serialink)
|
||||
val &= ~PCS_SCTRL_LOOP;
|
||||
else
|
||||
val |= PCS_SCTRL_LOOP;
|
||||
writel(val, gp->regs + PCS_SCTRL);
|
||||
}
|
||||
|
||||
#define STOP_TRIES 32
|
||||
|
||||
/* Must be invoked under gp->lock and gp->tx_lock. */
|
||||
@@ -1167,6 +1231,9 @@ static void gem_reset(struct gem *gp)
|
||||
|
||||
if (limit <= 0)
|
||||
printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name);
|
||||
|
||||
if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes)
|
||||
gem_pcs_reinit_adv(gp);
|
||||
}
|
||||
|
||||
/* Must be invoked under gp->lock and gp->tx_lock. */
|
||||
@@ -1323,7 +1390,7 @@ static int gem_set_link_modes(struct gem *gp)
|
||||
gp->phy_type == phy_serdes) {
|
||||
u32 pcs_lpa = readl(gp->regs + PCS_MIILP);
|
||||
|
||||
if (pcs_lpa & PCS_MIIADV_FD)
|
||||
if ((pcs_lpa & PCS_MIIADV_FD) || gp->phy_type == phy_serdes)
|
||||
full_duplex = 1;
|
||||
speed = SPEED_1000;
|
||||
}
|
||||
@@ -1487,6 +1554,9 @@ static void gem_link_timer(unsigned long data)
|
||||
val = readl(gp->regs + PCS_MIISTAT);
|
||||
|
||||
if ((val & PCS_MIISTAT_LS) != 0) {
|
||||
if (gp->lstate == link_up)
|
||||
goto restart;
|
||||
|
||||
gp->lstate = link_up;
|
||||
netif_carrier_on(gp->dev);
|
||||
(void)gem_set_link_modes(gp);
|
||||
@@ -1707,61 +1777,8 @@ static void gem_init_phy(struct gem *gp)
|
||||
if (gp->phy_mii.def && gp->phy_mii.def->ops->init)
|
||||
gp->phy_mii.def->ops->init(&gp->phy_mii);
|
||||
} else {
|
||||
u32 val;
|
||||
int limit;
|
||||
|
||||
/* Reset PCS unit. */
|
||||
val = readl(gp->regs + PCS_MIICTRL);
|
||||
val |= PCS_MIICTRL_RST;
|
||||
writel(val, gp->regs + PCS_MIICTRL);
|
||||
|
||||
limit = 32;
|
||||
while (readl(gp->regs + PCS_MIICTRL) & PCS_MIICTRL_RST) {
|
||||
udelay(100);
|
||||
if (limit-- <= 0)
|
||||
break;
|
||||
}
|
||||
if (limit <= 0)
|
||||
printk(KERN_WARNING "%s: PCS reset bit would not clear.\n",
|
||||
gp->dev->name);
|
||||
|
||||
/* Make sure PCS is disabled while changing advertisement
|
||||
* configuration.
|
||||
*/
|
||||
val = readl(gp->regs + PCS_CFG);
|
||||
val &= ~(PCS_CFG_ENABLE | PCS_CFG_TO);
|
||||
writel(val, gp->regs + PCS_CFG);
|
||||
|
||||
/* Advertise all capabilities except assymetric
|
||||
* pause.
|
||||
*/
|
||||
val = readl(gp->regs + PCS_MIIADV);
|
||||
val |= (PCS_MIIADV_FD | PCS_MIIADV_HD |
|
||||
PCS_MIIADV_SP | PCS_MIIADV_AP);
|
||||
writel(val, gp->regs + PCS_MIIADV);
|
||||
|
||||
/* Enable and restart auto-negotiation, disable wrapback/loopback,
|
||||
* and re-enable PCS.
|
||||
*/
|
||||
val = readl(gp->regs + PCS_MIICTRL);
|
||||
val |= (PCS_MIICTRL_RAN | PCS_MIICTRL_ANE);
|
||||
val &= ~PCS_MIICTRL_WB;
|
||||
writel(val, gp->regs + PCS_MIICTRL);
|
||||
|
||||
val = readl(gp->regs + PCS_CFG);
|
||||
val |= PCS_CFG_ENABLE;
|
||||
writel(val, gp->regs + PCS_CFG);
|
||||
|
||||
/* Make sure serialink loopback is off. The meaning
|
||||
* of this bit is logically inverted based upon whether
|
||||
* you are in Serialink or SERDES mode.
|
||||
*/
|
||||
val = readl(gp->regs + PCS_SCTRL);
|
||||
if (gp->phy_type == phy_serialink)
|
||||
val &= ~PCS_SCTRL_LOOP;
|
||||
else
|
||||
val |= PCS_SCTRL_LOOP;
|
||||
writel(val, gp->regs + PCS_SCTRL);
|
||||
gem_pcs_reset(gp);
|
||||
gem_pcs_reinit_adv(gp);
|
||||
}
|
||||
|
||||
/* Default aneg parameters */
|
||||
@@ -2679,6 +2696,21 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
cmd->speed = 0;
|
||||
cmd->duplex = cmd->port = cmd->phy_address =
|
||||
cmd->transceiver = cmd->autoneg = 0;
|
||||
|
||||
/* serdes means usually a Fibre connector, with most fixed */
|
||||
if (gp->phy_type == phy_serdes) {
|
||||
cmd->port = PORT_FIBRE;
|
||||
cmd->supported = (SUPPORTED_1000baseT_Half |
|
||||
SUPPORTED_1000baseT_Full |
|
||||
SUPPORTED_FIBRE | SUPPORTED_Autoneg |
|
||||
SUPPORTED_Pause | SUPPORTED_Asym_Pause);
|
||||
cmd->advertising = cmd->supported;
|
||||
cmd->transceiver = XCVR_INTERNAL;
|
||||
if (gp->lstate == link_up)
|
||||
cmd->speed = SPEED_1000;
|
||||
cmd->duplex = DUPLEX_FULL;
|
||||
cmd->autoneg = 1;
|
||||
}
|
||||
}
|
||||
cmd->maxtxpkt = cmd->maxrxpkt = 0;
|
||||
|
||||
|
Reference in New Issue
Block a user