git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
[pandora-kernel.git]
/
drivers
/
net
/
ethernet
/
marvell
/
sky2.c
diff --git
a/drivers/net/ethernet/marvell/sky2.c
b/drivers/net/ethernet/marvell/sky2.c
index
cbd026f
..
7803efa
100644
(file)
--- a/
drivers/net/ethernet/marvell/sky2.c
+++ b/
drivers/net/ethernet/marvell/sky2.c
@@
-50,7
+50,7
@@
#include "sky2.h"
#define DRV_NAME "sky2"
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.
29
"
+#define DRV_VERSION "1.
30
"
/*
* The Yukon II chipset takes 64 bit command blocks (called list elements)
/*
* The Yukon II chipset takes 64 bit command blocks (called list elements)
@@
-68,7
+68,7
@@
#define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
#define TX_MIN_PENDING (MAX_SKB_TX_LE+1)
#define TX_MAX_PENDING 1024
#define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
#define TX_MIN_PENDING (MAX_SKB_TX_LE+1)
#define TX_MAX_PENDING 1024
-#define TX_DEF_PENDING
127
+#define TX_DEF_PENDING
63
#define TX_WATCHDOG (5 * HZ)
#define NAPI_WEIGHT 64
#define TX_WATCHDOG (5 * HZ)
#define NAPI_WEIGHT 64
@@
-366,17
+366,6
@@
static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec);
}
} else {
gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec);
}
} else {
- if (hw->chip_id >= CHIP_ID_YUKON_OPT) {
- u16 ctrl2 = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL_2);
-
- /* enable PHY Reverse Auto-Negotiation */
- ctrl2 |= 1u << 13;
-
- /* Write PHY changes (SW-reset must follow) */
- gm_phy_write(hw, port, PHY_MARV_EXT_CTRL_2, ctrl2);
- }
-
-
/* disable energy detect */
ctrl &= ~PHY_M_PC_EN_DET_MSK;
/* disable energy detect */
ctrl &= ~PHY_M_PC_EN_DET_MSK;
@@
-880,6
+869,7
@@
static void sky2_wol_init(struct sky2_port *sky2)
/* block receiver */
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
/* block receiver */
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+ sky2_read32(hw, B0_CTST);
}
static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
}
static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
@@
-1285,6
+1275,14
@@
static void rx_set_checksum(struct sky2_port *sky2)
? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
}
? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
}
+/*
+ * Fixed initial key as seed to RSS.
+ */
+static const uint32_t rss_init_key[10] = {
+ 0x7c3351da, 0x51c5cf4e, 0x44adbdd1, 0xe8d38d18, 0x48897c43,
+ 0xb1d60e7e, 0x6a3dd760, 0x01a2e453, 0x16f46f13, 0x1a0e7b30
+};
+
/* Enable/disable receive hash calculation (RSS) */
static void rx_set_rss(struct net_device *dev, u32 features)
{
/* Enable/disable receive hash calculation (RSS) */
static void rx_set_rss(struct net_device *dev, u32 features)
{
@@
-1300,12
+1298,9
@@
static void rx_set_rss(struct net_device *dev, u32 features)
/* Program RSS initial values */
if (features & NETIF_F_RXHASH) {
/* Program RSS initial values */
if (features & NETIF_F_RXHASH) {
- u32 key[nkeys];
-
- get_random_bytes(key, nkeys * sizeof(u32));
for (i = 0; i < nkeys; i++)
sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4),
for (i = 0; i < nkeys; i++)
sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4),
- key[i]);
+
rss_init_
key[i]);
/* Need to turn on (undocumented) flag to make hashing work */
sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T),
/* Need to turn on (undocumented) flag to make hashing work */
sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T),
@@
-1728,6
+1723,8
@@
static int sky2_setup_irq(struct sky2_hw *hw, const char *name)
if (err)
dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
else {
if (err)
dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
else {
+ hw->flags |= SKY2_HW_IRQ_SETUP;
+
napi_enable(&hw->napi);
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
sky2_read32(hw, B0_IMSK);
napi_enable(&hw->napi);
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
sky2_read32(hw, B0_IMSK);
@@
-1738,7
+1735,7
@@
static int sky2_setup_irq(struct sky2_hw *hw, const char *name)
/* Bring up network interface. */
/* Bring up network interface. */
-static int sky2_
up
(struct net_device *dev)
+static int sky2_
open
(struct net_device *dev)
{
struct sky2_port *sky2 = netdev_priv(dev);
struct sky2_hw *hw = sky2->hw;
{
struct sky2_port *sky2 = netdev_priv(dev);
struct sky2_hw *hw = sky2->hw;
@@
-1758,6
+1755,11
@@
static int sky2_up(struct net_device *dev)
sky2_hw_up(sky2);
sky2_hw_up(sky2);
+ if (hw->chip_id == CHIP_ID_YUKON_OPT ||
+ hw->chip_id == CHIP_ID_YUKON_PRM ||
+ hw->chip_id == CHIP_ID_YUKON_OP_2)
+ imask |= Y2_IS_PHY_QLNK; /* enable PHY Quick Link */
+
/* Enable interrupts from phy/mac for port */
imask = sky2_read32(hw, B0_IMSK);
imask |= portirq_msk[port];
/* Enable interrupts from phy/mac for port */
imask = sky2_read32(hw, B0_IMSK);
imask |= portirq_msk[port];
@@
-2051,6
+2053,8
@@
static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)
sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+
+ sky2_read32(hw, B0_CTST);
}
static void sky2_hw_down(struct sky2_port *sky2)
}
static void sky2_hw_down(struct sky2_port *sky2)
@@
-2101,7
+2105,7
@@
static void sky2_hw_down(struct sky2_port *sky2)
}
/* Network shutdown */
}
/* Network shutdown */
-static int sky2_
down
(struct net_device *dev)
+static int sky2_
close
(struct net_device *dev)
{
struct sky2_port *sky2 = netdev_priv(dev);
struct sky2_hw *hw = sky2->hw;
{
struct sky2_port *sky2 = netdev_priv(dev);
struct sky2_hw *hw = sky2->hw;
@@
-2112,15
+2116,22
@@
static int sky2_down(struct net_device *dev)
netif_info(sky2, ifdown, dev, "disabling interface\n");
netif_info(sky2, ifdown, dev, "disabling interface\n");
- /* Disable port IRQ */
- sky2_write32(hw, B0_IMSK,
- sky2_read32(hw, B0_IMSK) & ~portirq_msk[sky2->port]);
- sky2_read32(hw, B0_IMSK);
-
if (hw->ports == 1) {
if (hw->ports == 1) {
+ sky2_write32(hw, B0_IMSK, 0);
+ sky2_read32(hw, B0_IMSK);
+
napi_disable(&hw->napi);
free_irq(hw->pdev->irq, hw);
napi_disable(&hw->napi);
free_irq(hw->pdev->irq, hw);
+ hw->flags &= ~SKY2_HW_IRQ_SETUP;
} else {
} else {
+ u32 imask;
+
+ /* Disable port IRQ */
+ imask = sky2_read32(hw, B0_IMSK);
+ imask &= ~portirq_msk[sky2->port];
+ sky2_write32(hw, B0_IMSK, imask);
+ sky2_read32(hw, B0_IMSK);
+
synchronize_irq(hw->pdev->irq);
napi_synchronize(&hw->napi);
}
synchronize_irq(hw->pdev->irq);
napi_synchronize(&hw->napi);
}
@@
-2598,7
+2609,7
@@
static inline void sky2_tx_done(struct net_device *dev, u16 last)
if (netif_running(dev)) {
sky2_tx_complete(sky2, last);
if (netif_running(dev)) {
sky2_tx_complete(sky2, last);
- /* Wake unless it's detached, and called e.g. from sky2_
down
() */
+ /* Wake unless it's detached, and called e.g. from sky2_
close
() */
if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
netif_wake_queue(dev);
}
if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
netif_wake_queue(dev);
}
@@
-3269,7
+3280,6
@@
static void sky2_reset(struct sky2_hw *hw)
hw->chip_id == CHIP_ID_YUKON_PRM ||
hw->chip_id == CHIP_ID_YUKON_OP_2) {
u16 reg;
hw->chip_id == CHIP_ID_YUKON_PRM ||
hw->chip_id == CHIP_ID_YUKON_OP_2) {
u16 reg;
- u32 msk;
if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
/* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
/* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
@@
-3292,11
+3302,6
@@
static void sky2_reset(struct sky2_hw *hw)
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
- /* enable PHY Quick Link */
- msk = sky2_read32(hw, B0_IMSK);
- msk |= Y2_IS_PHY_QLNK;
- sky2_write32(hw, B0_IMSK, msk);
-
/* check if PSMv2 was running before */
reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
if (reg & PCI_EXP_LNKCTL_ASPMC)
/* check if PSMv2 was running before */
reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
if (reg & PCI_EXP_LNKCTL_ASPMC)
@@
-3394,7
+3399,7
@@
static void sky2_detach(struct net_device *dev)
netif_tx_lock(dev);
netif_device_detach(dev); /* stop txq */
netif_tx_unlock(dev);
netif_tx_lock(dev);
netif_device_detach(dev); /* stop txq */
netif_tx_unlock(dev);
- sky2_
down
(dev);
+ sky2_
close
(dev);
}
}
}
}
@@
-3404,7
+3409,7
@@
static int sky2_reattach(struct net_device *dev)
int err = 0;
if (netif_running(dev)) {
int err = 0;
if (netif_running(dev)) {
- err = sky2_
up
(dev);
+ err = sky2_
open
(dev);
if (err) {
netdev_info(dev, "could not restart %d\n", err);
dev_close(dev);
if (err) {
netdev_info(dev, "could not restart %d\n", err);
dev_close(dev);
@@
-3421,10
+3426,13
@@
static void sky2_all_down(struct sky2_hw *hw)
{
int i;
{
int i;
- sky2_read32(hw, B0_IMSK);
- sky2_write32(hw, B0_IMSK, 0);
- synchronize_irq(hw->pdev->irq);
- napi_disable(&hw->napi);
+ if (hw->flags & SKY2_HW_IRQ_SETUP) {
+ sky2_read32(hw, B0_IMSK);
+ sky2_write32(hw, B0_IMSK, 0);
+
+ synchronize_irq(hw->pdev->irq);
+ napi_disable(&hw->napi);
+ }
for (i = 0; i < hw->ports; i++) {
struct net_device *dev = hw->dev[i];
for (i = 0; i < hw->ports; i++) {
struct net_device *dev = hw->dev[i];
@@
-3457,11
+3465,12
@@
static void sky2_all_up(struct sky2_hw *hw)
netif_wake_queue(dev);
}
netif_wake_queue(dev);
}
- sky2_write32(hw, B0_IMSK, imask);
- sky2_read32(hw, B0_IMSK);
-
- sky2_read32(hw, B0_Y2_SP_LISR);
- napi_enable(&hw->napi);
+ if (hw->flags & SKY2_HW_IRQ_SETUP) {
+ sky2_write32(hw, B0_IMSK, imask);
+ sky2_read32(hw, B0_IMSK);
+ sky2_read32(hw, B0_Y2_SP_LISR);
+ napi_enable(&hw->napi);
+ }
}
static void sky2_restart(struct work_struct *work)
}
static void sky2_restart(struct work_struct *work)
@@
-4082,6
+4091,16
@@
static int sky2_set_coalesce(struct net_device *dev,
return 0;
}
return 0;
}
+/*
+ * Hardware is limited to min of 128 and max of 2048 for ring size
+ * and rounded up to next power of two
+ * to avoid division in modulus calclation
+ */
+static unsigned long roundup_ring_size(unsigned long pending)
+{
+ return max(128ul, roundup_pow_of_two(pending+1));
+}
+
static void sky2_get_ringparam(struct net_device *dev,
struct ethtool_ringparam *ering)
{
static void sky2_get_ringparam(struct net_device *dev,
struct ethtool_ringparam *ering)
{
@@
-4109,7
+4128,7
@@
static int sky2_set_ringparam(struct net_device *dev,
sky2->rx_pending = ering->rx_pending;
sky2->tx_pending = ering->tx_pending;
sky2->rx_pending = ering->rx_pending;
sky2->tx_pending = ering->tx_pending;
- sky2->tx_ring_size = roundup_
pow_of_two(sky2->tx_pending+1
);
+ sky2->tx_ring_size = roundup_
ring_size(sky2->tx_pending
);
return sky2_reattach(dev);
}
return sky2_reattach(dev);
}
@@
-4567,7
+4586,7
@@
static int sky2_device_event(struct notifier_block *unused,
struct net_device *dev = ptr;
struct sky2_port *sky2 = netdev_priv(dev);
struct net_device *dev = ptr;
struct sky2_port *sky2 = netdev_priv(dev);
- if (dev->netdev_ops->ndo_open != sky2_
up
|| !sky2_debug)
+ if (dev->netdev_ops->ndo_open != sky2_
open
|| !sky2_debug)
return NOTIFY_DONE;
switch (event) {
return NOTIFY_DONE;
switch (event) {
@@
-4632,8
+4651,8
@@
static __exit void sky2_debug_cleanup(void)
not allowing netpoll on second port */
static const struct net_device_ops sky2_netdev_ops[2] = {
{
not allowing netpoll on second port */
static const struct net_device_ops sky2_netdev_ops[2] = {
{
- .ndo_open = sky2_
up
,
- .ndo_stop = sky2_
down
,
+ .ndo_open = sky2_
open
,
+ .ndo_stop = sky2_
close
,
.ndo_start_xmit = sky2_xmit_frame,
.ndo_do_ioctl = sky2_ioctl,
.ndo_validate_addr = eth_validate_addr,
.ndo_start_xmit = sky2_xmit_frame,
.ndo_do_ioctl = sky2_ioctl,
.ndo_validate_addr = eth_validate_addr,
@@
-4649,8
+4668,8
@@
static const struct net_device_ops sky2_netdev_ops[2] = {
#endif
},
{
#endif
},
{
- .ndo_open = sky2_
up
,
- .ndo_stop = sky2_
down
,
+ .ndo_open = sky2_
open
,
+ .ndo_stop = sky2_
close
,
.ndo_start_xmit = sky2_xmit_frame,
.ndo_do_ioctl = sky2_ioctl,
.ndo_validate_addr = eth_validate_addr,
.ndo_start_xmit = sky2_xmit_frame,
.ndo_do_ioctl = sky2_ioctl,
.ndo_validate_addr = eth_validate_addr,
@@
-4703,7
+4722,7
@@
static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
spin_lock_init(&sky2->phy_lock);
sky2->tx_pending = TX_DEF_PENDING;
spin_lock_init(&sky2->phy_lock);
sky2->tx_pending = TX_DEF_PENDING;
- sky2->tx_ring_size = roundup_
pow_of_two(TX_DEF_PENDING+1
);
+ sky2->tx_ring_size = roundup_
ring_size(TX_DEF_PENDING
);
sky2->rx_pending = RX_DEF_PENDING;
hw->dev[port] = dev;
sky2->rx_pending = RX_DEF_PENDING;
hw->dev[port] = dev;