Skip to content

Commit

Permalink
Merge branch 'upstream-davem' of master.kernel.org:/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/jgarzik/netdev-2.6
  • Loading branch information
David S. Miller committed Feb 6, 2008
2 parents 9c1ca6e + 370076d commit 655d2ce
Show file tree
Hide file tree
Showing 21 changed files with 398 additions and 255 deletions.
49 changes: 41 additions & 8 deletions drivers/net/forcedeth.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,8 @@ enum {
NvRegMIIStatus = 0x180,
#define NVREG_MIISTAT_ERROR 0x0001
#define NVREG_MIISTAT_LINKCHANGE 0x0008
#define NVREG_MIISTAT_MASK 0x000f
#define NVREG_MIISTAT_MASK2 0x000f
#define NVREG_MIISTAT_MASK_RW 0x0007
#define NVREG_MIISTAT_MASK_ALL 0x000f
NvRegMIIMask = 0x184,
#define NVREG_MII_LINKCHANGE 0x0008

Expand Down Expand Up @@ -624,6 +624,9 @@ union ring_type {
#define NV_MSI_X_VECTOR_TX 0x1
#define NV_MSI_X_VECTOR_OTHER 0x2

#define NV_RESTART_TX 0x1
#define NV_RESTART_RX 0x2

/* statistics */
struct nv_ethtool_str {
char name[ETH_GSTRING_LEN];
Expand Down Expand Up @@ -1061,7 +1064,7 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value)
u32 reg;
int retval;

writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
writel(NVREG_MIISTAT_MASK_RW, base + NvRegMIIStatus);

reg = readl(base + NvRegMIIControl);
if (reg & NVREG_MIICTL_INUSE) {
Expand Down Expand Up @@ -1432,16 +1435,30 @@ static void nv_mac_reset(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 temp1, temp2, temp3;

dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name);

writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);

/* save registers since they will be cleared on reset */
temp1 = readl(base + NvRegMacAddrA);
temp2 = readl(base + NvRegMacAddrB);
temp3 = readl(base + NvRegTransmitPoll);

writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset);
pci_push(base);
udelay(NV_MAC_RESET_DELAY);
writel(0, base + NvRegMacReset);
pci_push(base);
udelay(NV_MAC_RESET_DELAY);

/* restore saved registers */
writel(temp1, base + NvRegMacAddrA);
writel(temp2, base + NvRegMacAddrB);
writel(temp3, base + NvRegTransmitPoll);

writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
}
Expand Down Expand Up @@ -2767,6 +2784,7 @@ static int nv_update_linkspeed(struct net_device *dev)
int mii_status;
int retval = 0;
u32 control_1000, status_1000, phyreg, pause_flags, txreg;
u32 txrxFlags = 0;

/* BMSR_LSTATUS is latched, read it twice:
* we want the current value.
Expand Down Expand Up @@ -2862,6 +2880,16 @@ static int nv_update_linkspeed(struct net_device *dev)
np->duplex = newdup;
np->linkspeed = newls;

/* The transmitter and receiver must be restarted for safe update */
if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_START) {
txrxFlags |= NV_RESTART_TX;
nv_stop_tx(dev);
}
if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
txrxFlags |= NV_RESTART_RX;
nv_stop_rx(dev);
}

if (np->gigabit == PHY_GIGABIT) {
phyreg = readl(base + NvRegRandomSeed);
phyreg &= ~(0x3FF00);
Expand Down Expand Up @@ -2950,6 +2978,11 @@ static int nv_update_linkspeed(struct net_device *dev)
}
nv_update_pause(dev, pause_flags);

if (txrxFlags & NV_RESTART_TX)
nv_start_tx(dev);
if (txrxFlags & NV_RESTART_RX)
nv_start_rx(dev);

return retval;
}

Expand All @@ -2976,7 +3009,7 @@ static void nv_link_irq(struct net_device *dev)
u32 miistat;

miistat = readl(base + NvRegMIIStatus);
writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
writel(NVREG_MIISTAT_LINKCHANGE, base + NvRegMIIStatus);
dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat);

if (miistat & (NVREG_MIISTAT_LINKCHANGE))
Expand Down Expand Up @@ -4851,7 +4884,7 @@ static int nv_open(struct net_device *dev)

writel(0, base + NvRegMIIMask);
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);

writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1);
writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus);
Expand Down Expand Up @@ -4889,7 +4922,7 @@ static int nv_open(struct net_device *dev)

nv_disable_hw_interrupts(dev, np->irqmask);
pci_push(base);
writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
pci_push(base);

Expand All @@ -4912,7 +4945,7 @@ static int nv_open(struct net_device *dev)
{
u32 miistat;
miistat = readl(base + NvRegMIIStatus);
writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat);
}
/* set linkspeed to invalid value, thus force nv_update_linkspeed
Expand Down Expand Up @@ -5280,7 +5313,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
phystate &= ~NVREG_ADAPTCTL_RUNNING;
writel(phystate, base + NvRegAdapterControl);
}
writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);

if (id->driver_data & DEV_HAS_MGMT_UNIT) {
/* management unit running on the mac? */
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/gianfar_mii.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ int gfar_mdio_reset(struct mii_bus *bus)
struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
unsigned int timeout = PHY_INIT_TIMEOUT;

spin_lock_bh(&bus->mdio_lock);
mutex_lock(&bus->mdio_lock);

/* Reset the management interface */
gfar_write(&regs->miimcfg, MIIMCFG_RESET);
Expand All @@ -140,7 +140,7 @@ int gfar_mdio_reset(struct mii_bus *bus)
timeout--)
cpu_relax();

spin_unlock_bh(&bus->mdio_lock);
mutex_unlock(&bus->mdio_lock);

if(timeout <= 0) {
printk(KERN_ERR "%s: The MII Bus is stuck!\n",
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/iseries_veth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@ static const struct ethtool_ops ops = {
.get_link = veth_get_link,
};

static struct net_device * __init veth_probe_one(int vlan,
static struct net_device *veth_probe_one(int vlan,
struct vio_dev *vio_dev)
{
struct net_device *dev;
Expand Down
4 changes: 1 addition & 3 deletions drivers/net/ixgbe/ixgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,6 @@ struct ixgbe_ring {
u16 head;
u16 tail;

/* To protect race between sender and clean_tx_irq */
spinlock_t tx_lock;

struct ixgbe_queue_stats stats;

Expand Down Expand Up @@ -174,7 +172,6 @@ struct ixgbe_adapter {
struct vlan_group *vlgrp;
u16 bd_number;
u16 rx_buf_len;
atomic_t irq_sem;
struct work_struct reset_task;

/* TX */
Expand Down Expand Up @@ -244,6 +241,7 @@ extern const char ixgbe_driver_version[];

extern int ixgbe_up(struct ixgbe_adapter *adapter);
extern void ixgbe_down(struct ixgbe_adapter *adapter);
extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter);
extern void ixgbe_reset(struct ixgbe_adapter *adapter);
extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
extern void ixgbe_set_ethtool_ops(struct net_device *netdev);
Expand Down
91 changes: 54 additions & 37 deletions drivers/net/ixgbe/ixgbe_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,39 +103,59 @@ static int ixgbe_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
u32 link_speed = 0;
bool link_up;

ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
ecmd->port = PORT_FIBRE;
ecmd->supported = SUPPORTED_10000baseT_Full;
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->transceiver = XCVR_EXTERNAL;
if (hw->phy.media_type == ixgbe_media_type_copper) {
ecmd->supported |= (SUPPORTED_1000baseT_Full |
SUPPORTED_TP | SUPPORTED_Autoneg);

ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg);
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
ecmd->advertising |= ADVERTISED_10000baseT_Full;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
ecmd->advertising |= ADVERTISED_1000baseT_Full;

ecmd->port = PORT_TP;
} else {
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising = (ADVERTISED_10000baseT_Full |
ADVERTISED_FIBRE);
ecmd->port = PORT_FIBRE;
}

if (netif_carrier_ok(adapter->netdev)) {
ecmd->speed = SPEED_10000;
adapter->hw.mac.ops.check_link(hw, &(link_speed), &link_up);
if (link_up) {
ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
SPEED_10000 : SPEED_1000;
ecmd->duplex = DUPLEX_FULL;
} else {
ecmd->speed = -1;
ecmd->duplex = -1;
}

ecmd->autoneg = AUTONEG_DISABLE;
return 0;
}

static int ixgbe_set_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;

if (ecmd->autoneg == AUTONEG_ENABLE ||
ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
return -EINVAL;

if (netif_running(adapter->netdev)) {
ixgbe_down(adapter);
ixgbe_reset(adapter);
ixgbe_up(adapter);
} else {
ixgbe_reset(adapter);
switch (hw->phy.media_type) {
case ixgbe_media_type_fiber:
if ((ecmd->autoneg == AUTONEG_ENABLE) ||
(ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
return -EINVAL;
/* in this case we currently only support 10Gb/FULL */
break;
default:
break;
}

return 0;
Expand All @@ -147,7 +167,7 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;

pause->autoneg = AUTONEG_DISABLE;
pause->autoneg = (hw->fc.type == ixgbe_fc_full ? 1 : 0);

if (hw->fc.type == ixgbe_fc_rx_pause) {
pause->rx_pause = 1;
Expand All @@ -165,26 +185,24 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;

if (pause->autoneg == AUTONEG_ENABLE)
return -EINVAL;

if (pause->rx_pause && pause->tx_pause)
if ((pause->autoneg == AUTONEG_ENABLE) ||
(pause->rx_pause && pause->tx_pause))
hw->fc.type = ixgbe_fc_full;
else if (pause->rx_pause && !pause->tx_pause)
hw->fc.type = ixgbe_fc_rx_pause;
else if (!pause->rx_pause && pause->tx_pause)
hw->fc.type = ixgbe_fc_tx_pause;
else if (!pause->rx_pause && !pause->tx_pause)
hw->fc.type = ixgbe_fc_none;
else
return -EINVAL;

hw->fc.original_type = hw->fc.type;

if (netif_running(adapter->netdev)) {
ixgbe_down(adapter);
ixgbe_up(adapter);
} else {
if (netif_running(netdev))
ixgbe_reinit_locked(adapter);
else
ixgbe_reset(adapter);
}

return 0;
}
Expand All @@ -203,12 +221,10 @@ static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
else
adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;

if (netif_running(netdev)) {
ixgbe_down(adapter);
ixgbe_up(adapter);
} else {
if (netif_running(netdev))
ixgbe_reinit_locked(adapter);
else
ixgbe_reset(adapter);
}

return 0;
}
Expand Down Expand Up @@ -662,7 +678,10 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
return 0;
}

if (netif_running(adapter->netdev))
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
msleep(1);

if (netif_running(netdev))
ixgbe_down(adapter);

/*
Expand Down Expand Up @@ -733,6 +752,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
if (netif_running(adapter->netdev))
ixgbe_up(adapter);

clear_bit(__IXGBE_RESETTING, &adapter->state);
return err;
}

Expand Down Expand Up @@ -820,11 +840,8 @@ static int ixgbe_nway_reset(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);

if (netif_running(netdev)) {
ixgbe_down(adapter);
ixgbe_reset(adapter);
ixgbe_up(adapter);
}
if (netif_running(netdev))
ixgbe_reinit_locked(adapter);

return 0;
}
Expand Down
Loading

0 comments on commit 655d2ce

Please sign in to comment.