mirror of
https://github.com/suyu-emu/horinux.git
synced 2026-09-21 14:15:21 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (32 commits) net: Added ASSERT_RTNL() to dev_open() and dev_close(). can: Fix can_send() handling on dev_queue_xmit() failures netns: Fix arbitrary net_device-s corruptions on net_ns stop. netfilter: Kconfig: default DCCP/SCTP conntrack support to the protocol config values netfilter: nf_conntrack_sip: restrict RTP expect flushing on error to last request macvlan: Fix memleak on device removal/crash on module removal net/ipv4: correct RFC 1122 section reference in comment tcp FRTO: SACK variant is errorneously used with NewReno e1000e: don't return half-read eeprom on error ucc_geth: Don't use RX clock as TX clock. cxgb3: Use CAP_SYS_RAWIO for firmware pcnet32: delete non NAPI code from driver. fs_enet: Fix a memory leak in fs_enet_mdio_probe [netdrvr] eexpress: IPv6 fails - multicast problems 3c59x: use netstats in net_device structure 3c980-TX needs EXTRA_PREAMBLE fix warning in drivers/net/appletalk/cops.c e1000e: Add support for BM PHYs on ICH9 uli526x: fix endianness issues in the setup frame uli526x: initialize the hardware prior to requesting interrupts ...
This commit is contained in:
@@ -223,7 +223,9 @@ static struct platform_device orion5x_eth = {
|
||||
|
||||
void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
|
||||
{
|
||||
eth_data->shared = &orion5x_eth_shared;
|
||||
orion5x_eth.dev.platform_data = eth_data;
|
||||
|
||||
platform_device_register(&orion5x_eth_shared);
|
||||
platform_device_register(&orion5x_eth);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,9 @@ static struct resource mv643xx_eth0_resources[] = {
|
||||
|
||||
|
||||
static struct mv643xx_eth_platform_data eth0_pd = {
|
||||
.shared = &mv643xx_eth_shared_device,
|
||||
.port_number = 0,
|
||||
|
||||
.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
|
||||
.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
|
||||
.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
|
||||
@@ -88,7 +90,9 @@ static struct resource mv643xx_eth1_resources[] = {
|
||||
};
|
||||
|
||||
static struct mv643xx_eth_platform_data eth1_pd = {
|
||||
.shared = &mv643xx_eth_shared_device,
|
||||
.port_number = 1,
|
||||
|
||||
.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
|
||||
.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
|
||||
.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
|
||||
|
||||
@@ -239,6 +239,8 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id,
|
||||
|
||||
memset(&pdata, 0, sizeof(pdata));
|
||||
|
||||
pdata.shared = shared_pdev;
|
||||
|
||||
prop = of_get_property(np, "reg", NULL);
|
||||
if (!prop)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -341,6 +341,7 @@ static struct resource mv64x60_eth0_resources[] = {
|
||||
};
|
||||
|
||||
static struct mv643xx_eth_platform_data eth0_pd = {
|
||||
.shared = &mv64x60_eth_shared_device;
|
||||
.port_number = 0,
|
||||
};
|
||||
|
||||
@@ -366,6 +367,7 @@ static struct resource mv64x60_eth1_resources[] = {
|
||||
};
|
||||
|
||||
static struct mv643xx_eth_platform_data eth1_pd = {
|
||||
.shared = &mv64x60_eth_shared_device;
|
||||
.port_number = 1,
|
||||
};
|
||||
|
||||
@@ -391,6 +393,7 @@ static struct resource mv64x60_eth2_resources[] = {
|
||||
};
|
||||
|
||||
static struct mv643xx_eth_platform_data eth2_pd = {
|
||||
.shared = &mv64x60_eth_shared_device;
|
||||
.port_number = 2,
|
||||
};
|
||||
|
||||
|
||||
+36
-37
@@ -319,7 +319,7 @@ static struct vortex_chip_info {
|
||||
{"3c920B-EMB-WNM (ATI Radeon 9100 IGP)",
|
||||
PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, },
|
||||
{"3c980 Cyclone",
|
||||
PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
|
||||
PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
|
||||
|
||||
{"3c980C Python-T",
|
||||
PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
|
||||
@@ -600,7 +600,6 @@ struct vortex_private {
|
||||
struct sk_buff* tx_skbuff[TX_RING_SIZE];
|
||||
unsigned int cur_rx, cur_tx; /* The next free ring entry */
|
||||
unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
|
||||
struct net_device_stats stats; /* Generic stats */
|
||||
struct vortex_extra_stats xstats; /* NIC-specific extra stats */
|
||||
struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */
|
||||
dma_addr_t tx_skb_dma; /* Allocated DMA address for bus master ctrl DMA. */
|
||||
@@ -1875,7 +1874,7 @@ static void vortex_tx_timeout(struct net_device *dev)
|
||||
|
||||
issue_and_wait(dev, TxReset);
|
||||
|
||||
vp->stats.tx_errors++;
|
||||
dev->stats.tx_errors++;
|
||||
if (vp->full_bus_master_tx) {
|
||||
printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
|
||||
if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0)
|
||||
@@ -1887,7 +1886,7 @@ static void vortex_tx_timeout(struct net_device *dev)
|
||||
iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
|
||||
iowrite16(DownUnstall, ioaddr + EL3_CMD);
|
||||
} else {
|
||||
vp->stats.tx_dropped++;
|
||||
dev->stats.tx_dropped++;
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
|
||||
@@ -1928,8 +1927,8 @@ vortex_error(struct net_device *dev, int status)
|
||||
}
|
||||
dump_tx_ring(dev);
|
||||
}
|
||||
if (tx_status & 0x14) vp->stats.tx_fifo_errors++;
|
||||
if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
|
||||
if (tx_status & 0x14) dev->stats.tx_fifo_errors++;
|
||||
if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
|
||||
if (tx_status & 0x08) vp->xstats.tx_max_collisions++;
|
||||
iowrite8(0, ioaddr + TxStatus);
|
||||
if (tx_status & 0x30) { /* txJabber or txUnderrun */
|
||||
@@ -2051,8 +2050,8 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
if (vortex_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
|
||||
dev->name, tx_status);
|
||||
if (tx_status & 0x04) vp->stats.tx_fifo_errors++;
|
||||
if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
|
||||
if (tx_status & 0x04) dev->stats.tx_fifo_errors++;
|
||||
if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
|
||||
if (tx_status & 0x30) {
|
||||
issue_and_wait(dev, TxReset);
|
||||
}
|
||||
@@ -2350,7 +2349,7 @@ boomerang_interrupt(int irq, void *dev_id)
|
||||
} else {
|
||||
printk(KERN_DEBUG "boomerang_interrupt: no skb!\n");
|
||||
}
|
||||
/* vp->stats.tx_packets++; Counted below. */
|
||||
/* dev->stats.tx_packets++; Counted below. */
|
||||
dirty_tx++;
|
||||
}
|
||||
vp->dirty_tx = dirty_tx;
|
||||
@@ -2409,12 +2408,12 @@ static int vortex_rx(struct net_device *dev)
|
||||
unsigned char rx_error = ioread8(ioaddr + RxErrors);
|
||||
if (vortex_debug > 2)
|
||||
printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
|
||||
vp->stats.rx_errors++;
|
||||
if (rx_error & 0x01) vp->stats.rx_over_errors++;
|
||||
if (rx_error & 0x02) vp->stats.rx_length_errors++;
|
||||
if (rx_error & 0x04) vp->stats.rx_frame_errors++;
|
||||
if (rx_error & 0x08) vp->stats.rx_crc_errors++;
|
||||
if (rx_error & 0x10) vp->stats.rx_length_errors++;
|
||||
dev->stats.rx_errors++;
|
||||
if (rx_error & 0x01) dev->stats.rx_over_errors++;
|
||||
if (rx_error & 0x02) dev->stats.rx_length_errors++;
|
||||
if (rx_error & 0x04) dev->stats.rx_frame_errors++;
|
||||
if (rx_error & 0x08) dev->stats.rx_crc_errors++;
|
||||
if (rx_error & 0x10) dev->stats.rx_length_errors++;
|
||||
} else {
|
||||
/* The packet length: up to 4.5K!. */
|
||||
int pkt_len = rx_status & 0x1fff;
|
||||
@@ -2446,7 +2445,7 @@ static int vortex_rx(struct net_device *dev)
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
netif_rx(skb);
|
||||
dev->last_rx = jiffies;
|
||||
vp->stats.rx_packets++;
|
||||
dev->stats.rx_packets++;
|
||||
/* Wait a limited time to go to next packet. */
|
||||
for (i = 200; i >= 0; i--)
|
||||
if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
|
||||
@@ -2455,7 +2454,7 @@ static int vortex_rx(struct net_device *dev)
|
||||
} else if (vortex_debug > 0)
|
||||
printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
|
||||
"size %d.\n", dev->name, pkt_len);
|
||||
vp->stats.rx_dropped++;
|
||||
dev->stats.rx_dropped++;
|
||||
}
|
||||
issue_and_wait(dev, RxDiscard);
|
||||
}
|
||||
@@ -2482,12 +2481,12 @@ boomerang_rx(struct net_device *dev)
|
||||
unsigned char rx_error = rx_status >> 16;
|
||||
if (vortex_debug > 2)
|
||||
printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
|
||||
vp->stats.rx_errors++;
|
||||
if (rx_error & 0x01) vp->stats.rx_over_errors++;
|
||||
if (rx_error & 0x02) vp->stats.rx_length_errors++;
|
||||
if (rx_error & 0x04) vp->stats.rx_frame_errors++;
|
||||
if (rx_error & 0x08) vp->stats.rx_crc_errors++;
|
||||
if (rx_error & 0x10) vp->stats.rx_length_errors++;
|
||||
dev->stats.rx_errors++;
|
||||
if (rx_error & 0x01) dev->stats.rx_over_errors++;
|
||||
if (rx_error & 0x02) dev->stats.rx_length_errors++;
|
||||
if (rx_error & 0x04) dev->stats.rx_frame_errors++;
|
||||
if (rx_error & 0x08) dev->stats.rx_crc_errors++;
|
||||
if (rx_error & 0x10) dev->stats.rx_length_errors++;
|
||||
} else {
|
||||
/* The packet length: up to 4.5K!. */
|
||||
int pkt_len = rx_status & 0x1fff;
|
||||
@@ -2529,7 +2528,7 @@ boomerang_rx(struct net_device *dev)
|
||||
}
|
||||
netif_rx(skb);
|
||||
dev->last_rx = jiffies;
|
||||
vp->stats.rx_packets++;
|
||||
dev->stats.rx_packets++;
|
||||
}
|
||||
entry = (++vp->cur_rx) % RX_RING_SIZE;
|
||||
}
|
||||
@@ -2591,7 +2590,7 @@ vortex_down(struct net_device *dev, int final_down)
|
||||
del_timer_sync(&vp->rx_oom_timer);
|
||||
del_timer_sync(&vp->timer);
|
||||
|
||||
/* Turn off statistics ASAP. We update vp->stats below. */
|
||||
/* Turn off statistics ASAP. We update dev->stats below. */
|
||||
iowrite16(StatsDisable, ioaddr + EL3_CMD);
|
||||
|
||||
/* Disable the receiver and transmitter. */
|
||||
@@ -2728,7 +2727,7 @@ static struct net_device_stats *vortex_get_stats(struct net_device *dev)
|
||||
update_stats(ioaddr, dev);
|
||||
spin_unlock_irqrestore (&vp->lock, flags);
|
||||
}
|
||||
return &vp->stats;
|
||||
return &dev->stats;
|
||||
}
|
||||
|
||||
/* Update statistics.
|
||||
@@ -2748,18 +2747,18 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev)
|
||||
/* Unlike the 3c5x9 we need not turn off stats updates while reading. */
|
||||
/* Switch to the stats window, and read everything. */
|
||||
EL3WINDOW(6);
|
||||
vp->stats.tx_carrier_errors += ioread8(ioaddr + 0);
|
||||
vp->stats.tx_heartbeat_errors += ioread8(ioaddr + 1);
|
||||
vp->stats.tx_window_errors += ioread8(ioaddr + 4);
|
||||
vp->stats.rx_fifo_errors += ioread8(ioaddr + 5);
|
||||
vp->stats.tx_packets += ioread8(ioaddr + 6);
|
||||
vp->stats.tx_packets += (ioread8(ioaddr + 9)&0x30) << 4;
|
||||
dev->stats.tx_carrier_errors += ioread8(ioaddr + 0);
|
||||
dev->stats.tx_heartbeat_errors += ioread8(ioaddr + 1);
|
||||
dev->stats.tx_window_errors += ioread8(ioaddr + 4);
|
||||
dev->stats.rx_fifo_errors += ioread8(ioaddr + 5);
|
||||
dev->stats.tx_packets += ioread8(ioaddr + 6);
|
||||
dev->stats.tx_packets += (ioread8(ioaddr + 9)&0x30) << 4;
|
||||
/* Rx packets */ ioread8(ioaddr + 7); /* Must read to clear */
|
||||
/* Don't bother with register 9, an extension of registers 6&7.
|
||||
If we do use the 6&7 values the atomic update assumption above
|
||||
is invalid. */
|
||||
vp->stats.rx_bytes += ioread16(ioaddr + 10);
|
||||
vp->stats.tx_bytes += ioread16(ioaddr + 12);
|
||||
dev->stats.rx_bytes += ioread16(ioaddr + 10);
|
||||
dev->stats.tx_bytes += ioread16(ioaddr + 12);
|
||||
/* Extra stats for get_ethtool_stats() */
|
||||
vp->xstats.tx_multiple_collisions += ioread8(ioaddr + 2);
|
||||
vp->xstats.tx_single_collisions += ioread8(ioaddr + 3);
|
||||
@@ -2767,14 +2766,14 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev)
|
||||
EL3WINDOW(4);
|
||||
vp->xstats.rx_bad_ssd += ioread8(ioaddr + 12);
|
||||
|
||||
vp->stats.collisions = vp->xstats.tx_multiple_collisions
|
||||
dev->stats.collisions = vp->xstats.tx_multiple_collisions
|
||||
+ vp->xstats.tx_single_collisions
|
||||
+ vp->xstats.tx_max_collisions;
|
||||
|
||||
{
|
||||
u8 up = ioread8(ioaddr + 13);
|
||||
vp->stats.rx_bytes += (up & 0x0f) << 16;
|
||||
vp->stats.tx_bytes += (up & 0xf0) << 12;
|
||||
dev->stats.rx_bytes += (up & 0x0f) << 16;
|
||||
dev->stats.tx_bytes += (up & 0xf0) << 12;
|
||||
}
|
||||
|
||||
EL3WINDOW(old_window >> 13);
|
||||
|
||||
@@ -1273,20 +1273,6 @@ config PCNET32
|
||||
To compile this driver as a module, choose M here. The module
|
||||
will be called pcnet32.
|
||||
|
||||
config PCNET32_NAPI
|
||||
bool "Use RX polling (NAPI)"
|
||||
depends on PCNET32
|
||||
help
|
||||
NAPI is a new driver API designed to reduce CPU and interrupt load
|
||||
when the driver is receiving lots of packets from the card. It is
|
||||
still somewhat experimental and thus not yet enabled by default.
|
||||
|
||||
If your estimated Rx load is 10kpps or more, or if the card will be
|
||||
deployed on potentially unfriendly networks (e.g. in a firewall),
|
||||
then say Y here.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config AMD8111_ETH
|
||||
tristate "AMD 8111 (new PCI lance) support"
|
||||
depends on NET_PCI && PCI
|
||||
|
||||
@@ -499,19 +499,13 @@ static void cops_reset(struct net_device *dev, int sleep)
|
||||
{
|
||||
outb(0, ioaddr+DAYNA_RESET); /* Assert the reset port */
|
||||
inb(ioaddr+DAYNA_RESET); /* Clear the reset */
|
||||
if(sleep)
|
||||
{
|
||||
long snap=jiffies;
|
||||
|
||||
/* Let card finish initializing, about 1/3 second */
|
||||
while (time_before(jiffies, snap + HZ/3))
|
||||
schedule();
|
||||
}
|
||||
else
|
||||
mdelay(333);
|
||||
if (sleep)
|
||||
msleep(333);
|
||||
else
|
||||
mdelay(333);
|
||||
}
|
||||
|
||||
netif_wake_queue(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
static void cops_load (struct net_device *dev)
|
||||
|
||||
@@ -1425,13 +1425,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
res = netdev_set_master(slave_dev, bond_dev);
|
||||
if (res) {
|
||||
dprintk("Error %d calling netdev_set_master\n", res);
|
||||
goto err_close;
|
||||
goto err_restore_mac;
|
||||
}
|
||||
/* open the slave since the application closed it */
|
||||
res = dev_open(slave_dev);
|
||||
if (res) {
|
||||
dprintk("Openning slave %s failed\n", slave_dev->name);
|
||||
goto err_restore_mac;
|
||||
goto err_unset_master;
|
||||
}
|
||||
|
||||
new_slave->dev = slave_dev;
|
||||
@@ -1444,7 +1444,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
*/
|
||||
res = bond_alb_init_slave(bond, new_slave);
|
||||
if (res) {
|
||||
goto err_unset_master;
|
||||
goto err_close;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1619,7 +1619,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
|
||||
res = bond_create_slave_symlinks(bond_dev, slave_dev);
|
||||
if (res)
|
||||
goto err_unset_master;
|
||||
goto err_close;
|
||||
|
||||
printk(KERN_INFO DRV_NAME
|
||||
": %s: enslaving %s as a%s interface with a%s link.\n",
|
||||
@@ -1631,12 +1631,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
return 0;
|
||||
|
||||
/* Undo stages on error */
|
||||
err_unset_master:
|
||||
netdev_set_master(slave_dev, NULL);
|
||||
|
||||
err_close:
|
||||
dev_close(slave_dev);
|
||||
|
||||
err_unset_master:
|
||||
netdev_set_master(slave_dev, NULL);
|
||||
|
||||
err_restore_mac:
|
||||
if (!bond->params.fail_over_mac) {
|
||||
memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
|
||||
@@ -4936,7 +4936,9 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
|
||||
if (res < 0) {
|
||||
rtnl_lock();
|
||||
down_write(&bonding_rwsem);
|
||||
goto out_bond;
|
||||
bond_deinit(bond_dev);
|
||||
unregister_netdevice(bond_dev);
|
||||
goto out_rtnl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -4990,9 +4992,10 @@ err:
|
||||
destroy_workqueue(bond->wq);
|
||||
}
|
||||
|
||||
bond_destroy_sysfs();
|
||||
|
||||
rtnl_lock();
|
||||
bond_free_all();
|
||||
bond_destroy_sysfs();
|
||||
rtnl_unlock();
|
||||
out:
|
||||
return res;
|
||||
@@ -5004,9 +5007,10 @@ static void __exit bonding_exit(void)
|
||||
unregister_netdevice_notifier(&bond_netdev_notifier);
|
||||
unregister_inetaddr_notifier(&bond_inetaddr_notifier);
|
||||
|
||||
bond_destroy_sysfs();
|
||||
|
||||
rtnl_lock();
|
||||
bond_free_all();
|
||||
bond_destroy_sysfs();
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -146,29 +146,29 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
|
||||
": Unable remove bond %s due to open references.\n",
|
||||
ifname);
|
||||
res = -EPERM;
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
}
|
||||
printk(KERN_INFO DRV_NAME
|
||||
": %s is being deleted...\n",
|
||||
bond->dev->name);
|
||||
bond_destroy(bond);
|
||||
up_write(&bonding_rwsem);
|
||||
rtnl_unlock();
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
printk(KERN_ERR DRV_NAME
|
||||
": unable to delete non-existent bond %s\n", ifname);
|
||||
res = -ENODEV;
|
||||
up_write(&bonding_rwsem);
|
||||
rtnl_unlock();
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
err_no_cmd:
|
||||
printk(KERN_ERR DRV_NAME
|
||||
": no command found in bonding_masters. Use +ifname or -ifname.\n");
|
||||
res = -EPERM;
|
||||
return -EPERM;
|
||||
|
||||
out_unlock:
|
||||
up_write(&bonding_rwsem);
|
||||
rtnl_unlock();
|
||||
|
||||
/* Always return either count or an error. If you return 0, you'll
|
||||
* get called forever, which is bad.
|
||||
|
||||
@@ -1894,11 +1894,11 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
|
||||
u8 *fw_data;
|
||||
struct ch_mem_range t;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
if (copy_from_user(&t, useraddr, sizeof(t)))
|
||||
return -EFAULT;
|
||||
|
||||
/* Check t.len sanity ? */
|
||||
fw_data = kmalloc(t.len, GFP_KERNEL);
|
||||
if (!fw_data)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -648,6 +648,8 @@
|
||||
#define IFE_E_PHY_ID 0x02A80330
|
||||
#define IFE_PLUS_E_PHY_ID 0x02A80320
|
||||
#define IFE_C_E_PHY_ID 0x02A80310
|
||||
#define BME1000_E_PHY_ID 0x01410CB0
|
||||
#define BME1000_E_PHY_ID_R2 0x01410CB1
|
||||
|
||||
/* M88E1000 Specific Registers */
|
||||
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
|
||||
@@ -701,6 +703,14 @@
|
||||
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
|
||||
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800
|
||||
|
||||
/* BME1000 PHY Specific Control Register */
|
||||
#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */
|
||||
|
||||
|
||||
#define PHY_PAGE_SHIFT 5
|
||||
#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
|
||||
((reg) & MAX_PHY_REG_ADDRESS))
|
||||
|
||||
/*
|
||||
* Bits...
|
||||
* 15-5: page
|
||||
|
||||
@@ -127,7 +127,7 @@ struct e1000_buffer {
|
||||
/* arrays of page information for packet split */
|
||||
struct e1000_ps_page *ps_pages;
|
||||
};
|
||||
|
||||
struct page *page;
|
||||
};
|
||||
|
||||
struct e1000_ring {
|
||||
@@ -304,6 +304,7 @@ struct e1000_info {
|
||||
#define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5)
|
||||
#define FLAG_HAS_SWSM_ON_LOAD (1 << 6)
|
||||
#define FLAG_HAS_JUMBO_FRAMES (1 << 7)
|
||||
#define FLAG_IS_ICH (1 << 9)
|
||||
#define FLAG_HAS_SMART_POWER_DOWN (1 << 11)
|
||||
#define FLAG_IS_QUAD_PORT_A (1 << 12)
|
||||
#define FLAG_IS_QUAD_PORT (1 << 13)
|
||||
@@ -386,6 +387,7 @@ extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
|
||||
bool state);
|
||||
extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
|
||||
extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
|
||||
extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
|
||||
|
||||
extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
|
||||
extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
|
||||
@@ -443,6 +445,9 @@ extern s32 e1000e_get_phy_info_m88(struct e1000_hw *hw);
|
||||
extern s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
extern s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id);
|
||||
extern s32 e1000e_determine_phy_address(struct e1000_hw *hw);
|
||||
extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
|
||||
extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
|
||||
@@ -494,8 +494,12 @@ static int e1000_get_eeprom(struct net_device *netdev,
|
||||
for (i = 0; i < last_word - first_word + 1; i++) {
|
||||
ret_val = e1000_read_nvm(hw, first_word + i, 1,
|
||||
&eeprom_buff[i]);
|
||||
if (ret_val)
|
||||
if (ret_val) {
|
||||
/* a read error occurred, throw away the
|
||||
* result */
|
||||
memset(eeprom_buff, 0xff, sizeof(eeprom_buff));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -803,8 +807,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
|
||||
/* restore previous status */
|
||||
ew32(STATUS, before);
|
||||
|
||||
if ((mac->type != e1000_ich8lan) &&
|
||||
(mac->type != e1000_ich9lan)) {
|
||||
if (!(adapter->flags & FLAG_IS_ICH)) {
|
||||
REG_PATTERN_TEST(E1000_FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||
REG_PATTERN_TEST(E1000_FCAH, 0x0000FFFF, 0xFFFFFFFF);
|
||||
REG_PATTERN_TEST(E1000_FCT, 0x0000FFFF, 0xFFFFFFFF);
|
||||
@@ -824,15 +827,13 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
|
||||
|
||||
REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000);
|
||||
|
||||
before = (((mac->type == e1000_ich8lan) ||
|
||||
(mac->type == e1000_ich9lan)) ? 0x06C3B33E : 0x06DFB3FE);
|
||||
before = ((adapter->flags & FLAG_IS_ICH) ? 0x06C3B33E : 0x06DFB3FE);
|
||||
REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB);
|
||||
REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000);
|
||||
|
||||
REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF);
|
||||
REG_PATTERN_TEST(E1000_RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
|
||||
if ((mac->type != e1000_ich8lan) &&
|
||||
(mac->type != e1000_ich9lan))
|
||||
if (!(adapter->flags & FLAG_IS_ICH))
|
||||
REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF);
|
||||
REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
|
||||
REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF);
|
||||
@@ -911,9 +912,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
|
||||
|
||||
/* Test each interrupt */
|
||||
for (i = 0; i < 10; i++) {
|
||||
|
||||
if (((adapter->hw.mac.type == e1000_ich8lan) ||
|
||||
(adapter->hw.mac.type == e1000_ich9lan)) && i == 8)
|
||||
if ((adapter->flags & FLAG_IS_ICH) && (i == 8))
|
||||
continue;
|
||||
|
||||
/* Interrupt to test */
|
||||
@@ -1184,6 +1183,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 ctrl_reg = 0;
|
||||
u32 stat_reg = 0;
|
||||
u16 phy_reg = 0;
|
||||
|
||||
hw->mac.autoneg = 0;
|
||||
|
||||
@@ -1211,6 +1211,28 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
|
||||
E1000_CTRL_SPD_100 |/* Force Speed to 100 */
|
||||
E1000_CTRL_FD); /* Force Duplex to FULL */
|
||||
break;
|
||||
case e1000_phy_bm:
|
||||
/* Set Default MAC Interface speed to 1GB */
|
||||
e1e_rphy(hw, PHY_REG(2, 21), &phy_reg);
|
||||
phy_reg &= ~0x0007;
|
||||
phy_reg |= 0x006;
|
||||
e1e_wphy(hw, PHY_REG(2, 21), phy_reg);
|
||||
/* Assert SW reset for above settings to take effect */
|
||||
e1000e_commit_phy(hw);
|
||||
mdelay(1);
|
||||
/* Force Full Duplex */
|
||||
e1e_rphy(hw, PHY_REG(769, 16), &phy_reg);
|
||||
e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x000C);
|
||||
/* Set Link Up (in force link) */
|
||||
e1e_rphy(hw, PHY_REG(776, 16), &phy_reg);
|
||||
e1e_wphy(hw, PHY_REG(776, 16), phy_reg | 0x0040);
|
||||
/* Force Link */
|
||||
e1e_rphy(hw, PHY_REG(769, 16), &phy_reg);
|
||||
e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x0040);
|
||||
/* Set Early Link Enable */
|
||||
e1e_rphy(hw, PHY_REG(769, 20), &phy_reg);
|
||||
e1e_wphy(hw, PHY_REG(769, 20), phy_reg | 0x0400);
|
||||
/* fall through */
|
||||
default:
|
||||
/* force 1000, set loopback */
|
||||
e1e_wphy(hw, PHY_CONTROL, 0x4140);
|
||||
@@ -1224,8 +1246,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
|
||||
E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
|
||||
E1000_CTRL_FD); /* Force Duplex to FULL */
|
||||
|
||||
if ((adapter->hw.mac.type == e1000_ich8lan) ||
|
||||
(adapter->hw.mac.type == e1000_ich9lan))
|
||||
if (adapter->flags & FLAG_IS_ICH)
|
||||
ctrl_reg |= E1000_CTRL_SLU; /* Set Link Up */
|
||||
}
|
||||
|
||||
|
||||
@@ -216,6 +216,21 @@ enum e1e_registers {
|
||||
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
|
||||
#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
|
||||
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
|
||||
#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */
|
||||
#define IGP_PAGE_SHIFT 5
|
||||
#define PHY_REG_MASK 0x1F
|
||||
|
||||
#define BM_WUC_PAGE 800
|
||||
#define BM_WUC_ADDRESS_OPCODE 0x11
|
||||
#define BM_WUC_DATA_OPCODE 0x12
|
||||
#define BM_WUC_ENABLE_PAGE 769
|
||||
#define BM_WUC_ENABLE_REG 17
|
||||
#define BM_WUC_ENABLE_BIT (1 << 2)
|
||||
#define BM_WUC_HOST_WU_BIT (1 << 4)
|
||||
|
||||
#define BM_WUC PHY_REG(BM_WUC_PAGE, 1)
|
||||
#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2)
|
||||
#define BM_WUS PHY_REG(BM_WUC_PAGE, 3)
|
||||
|
||||
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
|
||||
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
|
||||
@@ -331,10 +346,16 @@ enum e1e_registers {
|
||||
#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
|
||||
#define E1000_DEV_ID_ICH8_IGP_M 0x104D
|
||||
#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD
|
||||
#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5
|
||||
#define E1000_DEV_ID_ICH9_IGP_M 0x10BF
|
||||
#define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB
|
||||
#define E1000_DEV_ID_ICH9_IGP_C 0x294C
|
||||
#define E1000_DEV_ID_ICH9_IFE 0x10C0
|
||||
#define E1000_DEV_ID_ICH9_IFE_GT 0x10C3
|
||||
#define E1000_DEV_ID_ICH9_IFE_G 0x10C2
|
||||
#define E1000_DEV_ID_ICH10_R_BM_LM 0x10CC
|
||||
#define E1000_DEV_ID_ICH10_R_BM_LF 0x10CD
|
||||
#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
|
||||
|
||||
#define E1000_FUNC_1 1
|
||||
|
||||
@@ -378,6 +399,7 @@ enum e1000_phy_type {
|
||||
e1000_phy_gg82563,
|
||||
e1000_phy_igp_3,
|
||||
e1000_phy_ife,
|
||||
e1000_phy_bm,
|
||||
};
|
||||
|
||||
enum e1000_bus_width {
|
||||
|
||||
@@ -38,6 +38,12 @@
|
||||
* 82566DM Gigabit Network Connection
|
||||
* 82566MC Gigabit Network Connection
|
||||
* 82566MM Gigabit Network Connection
|
||||
* 82567LM Gigabit Network Connection
|
||||
* 82567LF Gigabit Network Connection
|
||||
* 82567LM-2 Gigabit Network Connection
|
||||
* 82567LF-2 Gigabit Network Connection
|
||||
* 82567V-2 Gigabit Network Connection
|
||||
* 82562GT-3 10/100 Network Connection
|
||||
*/
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
@@ -198,6 +204,19 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
|
||||
phy->addr = 1;
|
||||
phy->reset_delay_us = 100;
|
||||
|
||||
/*
|
||||
* We may need to do this twice - once for IGP and if that fails,
|
||||
* we'll set BM func pointers and try again
|
||||
*/
|
||||
ret_val = e1000e_determine_phy_address(hw);
|
||||
if (ret_val) {
|
||||
hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm;
|
||||
hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm;
|
||||
ret_val = e1000e_determine_phy_address(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
phy->id = 0;
|
||||
while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&
|
||||
(i++ < 100)) {
|
||||
@@ -219,6 +238,13 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
|
||||
phy->type = e1000_phy_ife;
|
||||
phy->autoneg_mask = E1000_ALL_NOT_GIG;
|
||||
break;
|
||||
case BME1000_E_PHY_ID:
|
||||
phy->type = e1000_phy_bm;
|
||||
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
|
||||
hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm;
|
||||
hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm;
|
||||
hw->phy.ops.commit_phy = e1000e_phy_sw_reset;
|
||||
break;
|
||||
default:
|
||||
return -E1000_ERR_PHY;
|
||||
break;
|
||||
@@ -664,6 +690,7 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
|
||||
return e1000_get_phy_info_ife_ich8lan(hw);
|
||||
break;
|
||||
case e1000_phy_igp_3:
|
||||
case e1000_phy_bm:
|
||||
return e1000e_get_phy_info_igp(hw);
|
||||
break;
|
||||
default:
|
||||
@@ -728,7 +755,7 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
|
||||
s32 ret_val = 0;
|
||||
u16 data;
|
||||
|
||||
if (phy->type != e1000_phy_igp_3)
|
||||
if (phy->type == e1000_phy_ife)
|
||||
return ret_val;
|
||||
|
||||
phy_ctrl = er32(PHY_CTRL);
|
||||
@@ -1918,8 +1945,35 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
|
||||
ret_val = e1000e_copper_link_setup_igp(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
} else if (hw->phy.type == e1000_phy_bm) {
|
||||
ret_val = e1000e_copper_link_setup_m88(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
if (hw->phy.type == e1000_phy_ife) {
|
||||
ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, ®_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
reg_data &= ~IFE_PMC_AUTO_MDIX;
|
||||
|
||||
switch (hw->phy.mdix) {
|
||||
case 1:
|
||||
reg_data &= ~IFE_PMC_FORCE_MDIX;
|
||||
break;
|
||||
case 2:
|
||||
reg_data |= IFE_PMC_FORCE_MDIX;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
reg_data |= IFE_PMC_AUTO_MDIX;
|
||||
break;
|
||||
}
|
||||
ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
return e1000e_setup_copper_link(hw);
|
||||
}
|
||||
|
||||
@@ -2126,6 +2180,31 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
|
||||
reg_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000e_disable_gig_wol_ich8lan - disable gig during WoL
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* During S0 to Sx transition, it is possible the link remains at gig
|
||||
* instead of negotiating to a lower speed. Before going to Sx, set
|
||||
* 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
|
||||
* to a lower speed.
|
||||
*
|
||||
* Should only be called for ICH9 devices.
|
||||
**/
|
||||
void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
u32 phy_ctrl;
|
||||
|
||||
if (hw->mac.type == e1000_ich9lan) {
|
||||
phy_ctrl = er32(PHY_CTRL);
|
||||
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU |
|
||||
E1000_PHY_CTRL_GBE_DISABLE;
|
||||
ew32(PHY_CTRL, phy_ctrl);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_cleanup_led_ich8lan - Restore the default LED operation
|
||||
* @hw: pointer to the HW structure
|
||||
@@ -2247,6 +2326,7 @@ static struct e1000_nvm_operations ich8_nvm_ops = {
|
||||
struct e1000_info e1000_ich8_info = {
|
||||
.mac = e1000_ich8lan,
|
||||
.flags = FLAG_HAS_WOL
|
||||
| FLAG_IS_ICH
|
||||
| FLAG_RX_CSUM_ENABLED
|
||||
| FLAG_HAS_CTRLEXT_ON_LOAD
|
||||
| FLAG_HAS_AMT
|
||||
@@ -2262,6 +2342,7 @@ struct e1000_info e1000_ich8_info = {
|
||||
struct e1000_info e1000_ich9_info = {
|
||||
.mac = e1000_ich9lan,
|
||||
.flags = FLAG_HAS_JUMBO_FRAMES
|
||||
| FLAG_IS_ICH
|
||||
| FLAG_HAS_WOL
|
||||
| FLAG_RX_CSUM_ENABLED
|
||||
| FLAG_HAS_CTRLEXT_ON_LOAD
|
||||
|
||||
+322
-8
@@ -43,10 +43,11 @@
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/pm_qos_params.h>
|
||||
|
||||
#include "e1000.h"
|
||||
|
||||
#define DRV_VERSION "0.2.1"
|
||||
#define DRV_VERSION "0.3.3.3-k2"
|
||||
char e1000e_driver_name[] = "e1000e";
|
||||
const char e1000e_driver_version[] = DRV_VERSION;
|
||||
|
||||
@@ -340,6 +341,89 @@ no_buffers:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
|
||||
* @adapter: address of board private structure
|
||||
* @rx_ring: pointer to receive ring structure
|
||||
* @cleaned_count: number of buffers to allocate this pass
|
||||
**/
|
||||
|
||||
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
|
||||
int cleaned_count)
|
||||
{
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
struct e1000_rx_desc *rx_desc;
|
||||
struct e1000_ring *rx_ring = adapter->rx_ring;
|
||||
struct e1000_buffer *buffer_info;
|
||||
struct sk_buff *skb;
|
||||
unsigned int i;
|
||||
unsigned int bufsz = 256 -
|
||||
16 /* for skb_reserve */ -
|
||||
NET_IP_ALIGN;
|
||||
|
||||
i = rx_ring->next_to_use;
|
||||
buffer_info = &rx_ring->buffer_info[i];
|
||||
|
||||
while (cleaned_count--) {
|
||||
skb = buffer_info->skb;
|
||||
if (skb) {
|
||||
skb_trim(skb, 0);
|
||||
goto check_page;
|
||||
}
|
||||
|
||||
skb = netdev_alloc_skb(netdev, bufsz);
|
||||
if (unlikely(!skb)) {
|
||||
/* Better luck next round */
|
||||
adapter->alloc_rx_buff_failed++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make buffer alignment 2 beyond a 16 byte boundary
|
||||
* this will result in a 16 byte aligned IP header after
|
||||
* the 14 byte MAC header is removed
|
||||
*/
|
||||
skb_reserve(skb, NET_IP_ALIGN);
|
||||
|
||||
buffer_info->skb = skb;
|
||||
check_page:
|
||||
/* allocate a new page if necessary */
|
||||
if (!buffer_info->page) {
|
||||
buffer_info->page = alloc_page(GFP_ATOMIC);
|
||||
if (unlikely(!buffer_info->page)) {
|
||||
adapter->alloc_rx_buff_failed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!buffer_info->dma)
|
||||
buffer_info->dma = pci_map_page(pdev,
|
||||
buffer_info->page, 0,
|
||||
PAGE_SIZE,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
|
||||
rx_desc = E1000_RX_DESC(*rx_ring, i);
|
||||
rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
|
||||
|
||||
if (unlikely(++i == rx_ring->count))
|
||||
i = 0;
|
||||
buffer_info = &rx_ring->buffer_info[i];
|
||||
}
|
||||
|
||||
if (likely(rx_ring->next_to_use != i)) {
|
||||
rx_ring->next_to_use = i;
|
||||
if (unlikely(i-- == 0))
|
||||
i = (rx_ring->count - 1);
|
||||
|
||||
/* Force memory writes to complete before letting h/w
|
||||
* know there are new descriptors to fetch. (Only
|
||||
* applicable for weak-ordered memory model archs,
|
||||
* such as IA-64). */
|
||||
wmb();
|
||||
writel(i, adapter->hw.hw_addr + rx_ring->tail);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_clean_rx_irq - Send received data up the network stack; legacy
|
||||
* @adapter: board private structure
|
||||
@@ -782,6 +866,186 @@ next_desc:
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_consume_page - helper function
|
||||
**/
|
||||
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
|
||||
u16 length)
|
||||
{
|
||||
bi->page = NULL;
|
||||
skb->len += length;
|
||||
skb->data_len += length;
|
||||
skb->truesize += length;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
|
||||
* @adapter: board private structure
|
||||
*
|
||||
* the return value indicates whether actual cleaning was done, there
|
||||
* is no guarantee that everything was cleaned
|
||||
**/
|
||||
|
||||
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
|
||||
int *work_done, int work_to_do)
|
||||
{
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
struct e1000_ring *rx_ring = adapter->rx_ring;
|
||||
struct e1000_rx_desc *rx_desc, *next_rxd;
|
||||
struct e1000_buffer *buffer_info, *next_buffer;
|
||||
u32 length;
|
||||
unsigned int i;
|
||||
int cleaned_count = 0;
|
||||
bool cleaned = false;
|
||||
unsigned int total_rx_bytes=0, total_rx_packets=0;
|
||||
|
||||
i = rx_ring->next_to_clean;
|
||||
rx_desc = E1000_RX_DESC(*rx_ring, i);
|
||||
buffer_info = &rx_ring->buffer_info[i];
|
||||
|
||||
while (rx_desc->status & E1000_RXD_STAT_DD) {
|
||||
struct sk_buff *skb;
|
||||
u8 status;
|
||||
|
||||
if (*work_done >= work_to_do)
|
||||
break;
|
||||
(*work_done)++;
|
||||
|
||||
status = rx_desc->status;
|
||||
skb = buffer_info->skb;
|
||||
buffer_info->skb = NULL;
|
||||
|
||||
++i;
|
||||
if (i == rx_ring->count)
|
||||
i = 0;
|
||||
next_rxd = E1000_RX_DESC(*rx_ring, i);
|
||||
prefetch(next_rxd);
|
||||
|
||||
next_buffer = &rx_ring->buffer_info[i];
|
||||
|
||||
cleaned = true;
|
||||
cleaned_count++;
|
||||
pci_unmap_page(pdev, buffer_info->dma, PAGE_SIZE,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
buffer_info->dma = 0;
|
||||
|
||||
length = le16_to_cpu(rx_desc->length);
|
||||
|
||||
/* errors is only valid for DD + EOP descriptors */
|
||||
if (unlikely((status & E1000_RXD_STAT_EOP) &&
|
||||
(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
|
||||
/* recycle both page and skb */
|
||||
buffer_info->skb = skb;
|
||||
/* an error means any chain goes out the window
|
||||
* too */
|
||||
if (rx_ring->rx_skb_top)
|
||||
dev_kfree_skb(rx_ring->rx_skb_top);
|
||||
rx_ring->rx_skb_top = NULL;
|
||||
goto next_desc;
|
||||
}
|
||||
|
||||
#define rxtop rx_ring->rx_skb_top
|
||||
if (!(status & E1000_RXD_STAT_EOP)) {
|
||||
/* this descriptor is only the beginning (or middle) */
|
||||
if (!rxtop) {
|
||||
/* this is the beginning of a chain */
|
||||
rxtop = skb;
|
||||
skb_fill_page_desc(rxtop, 0, buffer_info->page,
|
||||
0, length);
|
||||
} else {
|
||||
/* this is the middle of a chain */
|
||||
skb_fill_page_desc(rxtop,
|
||||
skb_shinfo(rxtop)->nr_frags,
|
||||
buffer_info->page, 0, length);
|
||||
/* re-use the skb, only consumed the page */
|
||||
buffer_info->skb = skb;
|
||||
}
|
||||
e1000_consume_page(buffer_info, rxtop, length);
|
||||
goto next_desc;
|
||||
} else {
|
||||
if (rxtop) {
|
||||
/* end of the chain */
|
||||
skb_fill_page_desc(rxtop,
|
||||
skb_shinfo(rxtop)->nr_frags,
|
||||
buffer_info->page, 0, length);
|
||||
/* re-use the current skb, we only consumed the
|
||||
* page */
|
||||
buffer_info->skb = skb;
|
||||
skb = rxtop;
|
||||
rxtop = NULL;
|
||||
e1000_consume_page(buffer_info, skb, length);
|
||||
} else {
|
||||
/* no chain, got EOP, this buf is the packet
|
||||
* copybreak to save the put_page/alloc_page */
|
||||
if (length <= copybreak &&
|
||||
skb_tailroom(skb) >= length) {
|
||||
u8 *vaddr;
|
||||
vaddr = kmap_atomic(buffer_info->page,
|
||||
KM_SKB_DATA_SOFTIRQ);
|
||||
memcpy(skb_tail_pointer(skb), vaddr,
|
||||
length);
|
||||
kunmap_atomic(vaddr,
|
||||
KM_SKB_DATA_SOFTIRQ);
|
||||
/* re-use the page, so don't erase
|
||||
* buffer_info->page */
|
||||
skb_put(skb, length);
|
||||
} else {
|
||||
skb_fill_page_desc(skb, 0,
|
||||
buffer_info->page, 0,
|
||||
length);
|
||||
e1000_consume_page(buffer_info, skb,
|
||||
length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Receive Checksum Offload XXX recompute due to CRC strip? */
|
||||
e1000_rx_checksum(adapter,
|
||||
(u32)(status) |
|
||||
((u32)(rx_desc->errors) << 24),
|
||||
le16_to_cpu(rx_desc->csum), skb);
|
||||
|
||||
/* probably a little skewed due to removing CRC */
|
||||
total_rx_bytes += skb->len;
|
||||
total_rx_packets++;
|
||||
|
||||
/* eth type trans needs skb->data to point to something */
|
||||
if (!pskb_may_pull(skb, ETH_HLEN)) {
|
||||
ndev_err(netdev, "pskb_may_pull failed.\n");
|
||||
dev_kfree_skb(skb);
|
||||
goto next_desc;
|
||||
}
|
||||
|
||||
e1000_receive_skb(adapter, netdev, skb, status,
|
||||
rx_desc->special);
|
||||
|
||||
next_desc:
|
||||
rx_desc->status = 0;
|
||||
|
||||
/* return some buffers to hardware, one at a time is too slow */
|
||||
if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
|
||||
adapter->alloc_rx_buf(adapter, cleaned_count);
|
||||
cleaned_count = 0;
|
||||
}
|
||||
|
||||
/* use prefetched values */
|
||||
rx_desc = next_rxd;
|
||||
buffer_info = next_buffer;
|
||||
}
|
||||
rx_ring->next_to_clean = i;
|
||||
|
||||
cleaned_count = e1000_desc_unused(rx_ring);
|
||||
if (cleaned_count)
|
||||
adapter->alloc_rx_buf(adapter, cleaned_count);
|
||||
|
||||
adapter->total_rx_bytes += total_rx_bytes;
|
||||
adapter->total_rx_packets += total_rx_packets;
|
||||
adapter->net_stats.rx_bytes += total_rx_bytes;
|
||||
adapter->net_stats.rx_packets += total_rx_packets;
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_clean_rx_ring - Free Rx Buffers per Queue
|
||||
* @adapter: board private structure
|
||||
@@ -802,6 +1066,10 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
|
||||
pci_unmap_single(pdev, buffer_info->dma,
|
||||
adapter->rx_buffer_len,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
|
||||
pci_unmap_page(pdev, buffer_info->dma,
|
||||
PAGE_SIZE,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
|
||||
pci_unmap_single(pdev, buffer_info->dma,
|
||||
adapter->rx_ps_bsize0,
|
||||
@@ -809,6 +1077,11 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
|
||||
buffer_info->dma = 0;
|
||||
}
|
||||
|
||||
if (buffer_info->page) {
|
||||
put_page(buffer_info->page);
|
||||
buffer_info->page = NULL;
|
||||
}
|
||||
|
||||
if (buffer_info->skb) {
|
||||
dev_kfree_skb(buffer_info->skb);
|
||||
buffer_info->skb = NULL;
|
||||
@@ -1755,10 +2028,12 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
|
||||
* a lot of memory, since we allocate 3 pages at all times
|
||||
* per packet.
|
||||
*/
|
||||
adapter->rx_ps_pages = 0;
|
||||
pages = PAGE_USE_COUNT(adapter->netdev->mtu);
|
||||
if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
|
||||
if (!(adapter->flags & FLAG_IS_ICH) && (pages <= 3) &&
|
||||
(PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
|
||||
adapter->rx_ps_pages = pages;
|
||||
else
|
||||
adapter->rx_ps_pages = 0;
|
||||
|
||||
if (adapter->rx_ps_pages) {
|
||||
/* Configure extra packet-split registers */
|
||||
@@ -1819,9 +2094,12 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
|
||||
sizeof(union e1000_rx_desc_packet_split);
|
||||
adapter->clean_rx = e1000_clean_rx_irq_ps;
|
||||
adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
|
||||
} else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
|
||||
rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
|
||||
adapter->clean_rx = e1000_clean_jumbo_rx_irq;
|
||||
adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
|
||||
} else {
|
||||
rdlen = rx_ring->count *
|
||||
sizeof(struct e1000_rx_desc);
|
||||
rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
|
||||
adapter->clean_rx = e1000_clean_rx_irq;
|
||||
adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
|
||||
}
|
||||
@@ -1885,8 +2163,21 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
|
||||
* units), e.g. using jumbo frames when setting to E1000_ERT_2048
|
||||
*/
|
||||
if ((adapter->flags & FLAG_HAS_ERT) &&
|
||||
(adapter->netdev->mtu > ETH_DATA_LEN))
|
||||
ew32(ERT, E1000_ERT_2048);
|
||||
(adapter->netdev->mtu > ETH_DATA_LEN)) {
|
||||
u32 rxdctl = er32(RXDCTL(0));
|
||||
ew32(RXDCTL(0), rxdctl | 0x3);
|
||||
ew32(ERT, E1000_ERT_2048 | (1 << 13));
|
||||
/*
|
||||
* With jumbo frames and early-receive enabled, excessive
|
||||
* C4->C2 latencies result in dropped transactions.
|
||||
*/
|
||||
pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
|
||||
e1000e_driver_name, 55);
|
||||
} else {
|
||||
pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
|
||||
e1000e_driver_name,
|
||||
PM_QOS_DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
/* Enable Receives */
|
||||
ew32(RCTL, rctl);
|
||||
@@ -2155,6 +2446,14 @@ void e1000e_reset(struct e1000_adapter *adapter)
|
||||
|
||||
/* Allow time for pending master requests to run */
|
||||
mac->ops.reset_hw(hw);
|
||||
|
||||
/*
|
||||
* For parts with AMT enabled, let the firmware know
|
||||
* that the network interface is in control
|
||||
*/
|
||||
if ((adapter->flags & FLAG_HAS_AMT) && e1000e_check_mng_mode(hw))
|
||||
e1000_get_hw_control(adapter);
|
||||
|
||||
ew32(WUC, 0);
|
||||
|
||||
if (mac->ops.init_hw(hw))
|
||||
@@ -3469,6 +3768,8 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
|
||||
* means we reserve 2 more, this pushes us to allocate from the next
|
||||
* larger slab size.
|
||||
* i.e. RXBUFFER_2048 --> size-4096 slab
|
||||
* However with the new *_jumbo_rx* routines, jumbo receives will use
|
||||
* fragmented skbs
|
||||
*/
|
||||
|
||||
if (max_frame <= 256)
|
||||
@@ -3626,6 +3927,9 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
ew32(CTRL_EXT, ctrl_ext);
|
||||
}
|
||||
|
||||
if (adapter->flags & FLAG_IS_ICH)
|
||||
e1000e_disable_gig_wol_ich8lan(&adapter->hw);
|
||||
|
||||
/* Allow time for pending master requests to run */
|
||||
e1000e_disable_pcie_master(&adapter->hw);
|
||||
|
||||
@@ -4292,6 +4596,13 @@ static struct pci_device_id e1000_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
|
||||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
@@ -4326,7 +4637,9 @@ static int __init e1000_init_module(void)
|
||||
printk(KERN_INFO "%s: Copyright (c) 1999-2008 Intel Corporation.\n",
|
||||
e1000e_driver_name);
|
||||
ret = pci_register_driver(&e1000_driver);
|
||||
|
||||
pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name,
|
||||
PM_QOS_DEFAULT_VALUE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
module_init(e1000_init_module);
|
||||
@@ -4340,6 +4653,7 @@ module_init(e1000_init_module);
|
||||
static void __exit e1000_exit_module(void)
|
||||
{
|
||||
pci_unregister_driver(&e1000_driver);
|
||||
pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name);
|
||||
}
|
||||
module_exit(e1000_exit_module);
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@ static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
|
||||
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
|
||||
static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
|
||||
static s32 e1000_wait_autoneg(struct e1000_hw *hw);
|
||||
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
|
||||
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
|
||||
u16 *data, bool read);
|
||||
|
||||
/* Cable length tables */
|
||||
static const u16 e1000_m88_cable_length_table[] =
|
||||
@@ -465,6 +468,10 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
|
||||
if (phy->disable_polarity_correction == 1)
|
||||
phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
|
||||
|
||||
/* Enable downshift on BM (disabled by default) */
|
||||
if (phy->type == e1000_phy_bm)
|
||||
phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
|
||||
|
||||
ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
@@ -1776,6 +1783,10 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
|
||||
case IFE_C_E_PHY_ID:
|
||||
phy_type = e1000_phy_ife;
|
||||
break;
|
||||
case BME1000_E_PHY_ID:
|
||||
case BME1000_E_PHY_ID_R2:
|
||||
phy_type = e1000_phy_bm;
|
||||
break;
|
||||
default:
|
||||
phy_type = e1000_phy_unknown;
|
||||
break;
|
||||
@@ -1783,6 +1794,273 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
|
||||
return phy_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000e_determine_phy_address - Determines PHY address.
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This uses a trial and error method to loop through possible PHY
|
||||
* addresses. It tests each by reading the PHY ID registers and
|
||||
* checking for a match.
|
||||
**/
|
||||
s32 e1000e_determine_phy_address(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_PHY_TYPE;
|
||||
u32 phy_addr= 0;
|
||||
u32 i = 0;
|
||||
enum e1000_phy_type phy_type = e1000_phy_unknown;
|
||||
|
||||
do {
|
||||
for (phy_addr = 0; phy_addr < 4; phy_addr++) {
|
||||
hw->phy.addr = phy_addr;
|
||||
e1000e_get_phy_id(hw);
|
||||
phy_type = e1000e_get_phy_type_from_id(hw->phy.id);
|
||||
|
||||
/*
|
||||
* If phy_type is valid, break - we found our
|
||||
* PHY address
|
||||
*/
|
||||
if (phy_type != e1000_phy_unknown) {
|
||||
ret_val = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
} while ((ret_val != 0) && (i < 100));
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
|
||||
* @page: page to access
|
||||
*
|
||||
* Returns the phy address for the page requested.
|
||||
**/
|
||||
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
|
||||
{
|
||||
u32 phy_addr = 2;
|
||||
|
||||
if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
|
||||
phy_addr = 1;
|
||||
|
||||
return phy_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000e_write_phy_reg_bm - Write BM PHY register
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: register offset to write to
|
||||
* @data: data to write at register offset
|
||||
*
|
||||
* Acquires semaphore, if necessary, then writes the data to PHY register
|
||||
* at the offset. Release any acquired semaphores before exiting.
|
||||
**/
|
||||
s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
{
|
||||
s32 ret_val;
|
||||
u32 page_select = 0;
|
||||
u32 page = offset >> IGP_PAGE_SHIFT;
|
||||
u32 page_shift = 0;
|
||||
|
||||
/* Page 800 works differently than the rest so it has its own func */
|
||||
if (page == BM_WUC_PAGE) {
|
||||
ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
|
||||
false);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_val = hw->phy.ops.acquire_phy(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
|
||||
|
||||
if (offset > MAX_PHY_MULTI_PAGE_REG) {
|
||||
/*
|
||||
* Page select is register 31 for phy address 1 and 22 for
|
||||
* phy address 2 and 3. Page select is shifted only for
|
||||
* phy address 1.
|
||||
*/
|
||||
if (hw->phy.addr == 1) {
|
||||
page_shift = IGP_PAGE_SHIFT;
|
||||
page_select = IGP01E1000_PHY_PAGE_SELECT;
|
||||
} else {
|
||||
page_shift = 0;
|
||||
page_select = BM_PHY_PAGE_SELECT;
|
||||
}
|
||||
|
||||
/* Page is shifted left, PHY expects (page x 32) */
|
||||
ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
|
||||
(page << page_shift));
|
||||
if (ret_val) {
|
||||
hw->phy.ops.release_phy(hw);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
|
||||
data);
|
||||
|
||||
hw->phy.ops.release_phy(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000e_read_phy_reg_bm - Read BM PHY register
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: register offset to be read
|
||||
* @data: pointer to the read data
|
||||
*
|
||||
* Acquires semaphore, if necessary, then reads the PHY register at offset
|
||||
* and storing the retrieved information in data. Release any acquired
|
||||
* semaphores before exiting.
|
||||
**/
|
||||
s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
{
|
||||
s32 ret_val;
|
||||
u32 page_select = 0;
|
||||
u32 page = offset >> IGP_PAGE_SHIFT;
|
||||
u32 page_shift = 0;
|
||||
|
||||
/* Page 800 works differently than the rest so it has its own func */
|
||||
if (page == BM_WUC_PAGE) {
|
||||
ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
|
||||
true);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_val = hw->phy.ops.acquire_phy(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
|
||||
|
||||
if (offset > MAX_PHY_MULTI_PAGE_REG) {
|
||||
/*
|
||||
* Page select is register 31 for phy address 1 and 22 for
|
||||
* phy address 2 and 3. Page select is shifted only for
|
||||
* phy address 1.
|
||||
*/
|
||||
if (hw->phy.addr == 1) {
|
||||
page_shift = IGP_PAGE_SHIFT;
|
||||
page_select = IGP01E1000_PHY_PAGE_SELECT;
|
||||
} else {
|
||||
page_shift = 0;
|
||||
page_select = BM_PHY_PAGE_SELECT;
|
||||
}
|
||||
|
||||
/* Page is shifted left, PHY expects (page x 32) */
|
||||
ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
|
||||
(page << page_shift));
|
||||
if (ret_val) {
|
||||
hw->phy.ops.release_phy(hw);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
|
||||
data);
|
||||
hw->phy.ops.release_phy(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: register offset to be read or written
|
||||
* @data: pointer to the data to read or write
|
||||
* @read: determines if operation is read or write
|
||||
*
|
||||
* Acquires semaphore, if necessary, then reads the PHY register at offset
|
||||
* and storing the retrieved information in data. Release any acquired
|
||||
* semaphores before exiting. Note that procedure to read the wakeup
|
||||
* registers are different. It works as such:
|
||||
* 1) Set page 769, register 17, bit 2 = 1
|
||||
* 2) Set page to 800 for host (801 if we were manageability)
|
||||
* 3) Write the address using the address opcode (0x11)
|
||||
* 4) Read or write the data using the data opcode (0x12)
|
||||
* 5) Restore 769_17.2 to its original value
|
||||
**/
|
||||
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
|
||||
u16 *data, bool read)
|
||||
{
|
||||
s32 ret_val;
|
||||
u16 reg = ((u16)offset) & PHY_REG_MASK;
|
||||
u16 phy_reg = 0;
|
||||
u8 phy_acquired = 1;
|
||||
|
||||
|
||||
ret_val = hw->phy.ops.acquire_phy(hw);
|
||||
if (ret_val) {
|
||||
phy_acquired = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* All operations in this function are phy address 1 */
|
||||
hw->phy.addr = 1;
|
||||
|
||||
/* Set page 769 */
|
||||
e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
|
||||
(BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
|
||||
|
||||
ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* First clear bit 4 to avoid a power state change */
|
||||
phy_reg &= ~(BM_WUC_HOST_WU_BIT);
|
||||
ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Write bit 2 = 1, and clear bit 4 to 769_17 */
|
||||
ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG,
|
||||
phy_reg | BM_WUC_ENABLE_BIT);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Select page 800 */
|
||||
ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
|
||||
(BM_WUC_PAGE << IGP_PAGE_SHIFT));
|
||||
|
||||
/* Write the page 800 offset value using opcode 0x11 */
|
||||
ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
if (read) {
|
||||
/* Read the page 800 value using opcode 0x12 */
|
||||
ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
|
||||
data);
|
||||
} else {
|
||||
/* Read the page 800 value using opcode 0x12 */
|
||||
ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
|
||||
*data);
|
||||
}
|
||||
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Restore 769_17.2 to its original value
|
||||
* Set page 769
|
||||
*/
|
||||
e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
|
||||
(BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
|
||||
|
||||
/* Clear 769_17.2 */
|
||||
ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
|
||||
|
||||
out:
|
||||
if (phy_acquired == 1)
|
||||
hw->phy.ops.release_phy(hw);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000e_commit_phy - Soft PHY reset
|
||||
* @hw: pointer to the HW structure
|
||||
|
||||
@@ -202,7 +202,7 @@ static unsigned short start_code[] = {
|
||||
0x0000,Cmd_MCast,
|
||||
0x0076, /* link to next command */
|
||||
#define CONF_NR_MULTICAST 0x44
|
||||
0x0000, /* number of multicast addresses */
|
||||
0x0000, /* number of bytes in multicast address(es) */
|
||||
#define CONF_MULTICAST 0x46
|
||||
0x0000, 0x0000, 0x0000, /* some addresses */
|
||||
0x0000, 0x0000, 0x0000,
|
||||
@@ -1569,7 +1569,7 @@ static void eexp_hw_init586(struct net_device *dev)
|
||||
|
||||
static void eexp_setup_filter(struct net_device *dev)
|
||||
{
|
||||
struct dev_mc_list *dmi = dev->mc_list;
|
||||
struct dev_mc_list *dmi;
|
||||
unsigned short ioaddr = dev->base_addr;
|
||||
int count = dev->mc_count;
|
||||
int i;
|
||||
@@ -1580,9 +1580,9 @@ static void eexp_setup_filter(struct net_device *dev)
|
||||
}
|
||||
|
||||
outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR);
|
||||
outw(count, ioaddr+SHADOW(CONF_NR_MULTICAST));
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned short *data = (unsigned short *)dmi->dmi_addr;
|
||||
outw(6*count, ioaddr+SHADOW(CONF_NR_MULTICAST));
|
||||
for (i = 0, dmi = dev->mc_list; i < count; i++, dmi = dmi->next) {
|
||||
unsigned short *data;
|
||||
if (!dmi) {
|
||||
printk(KERN_INFO "%s: too few multicast addresses\n", dev->name);
|
||||
break;
|
||||
@@ -1591,6 +1591,7 @@ static void eexp_setup_filter(struct net_device *dev)
|
||||
printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);
|
||||
continue;
|
||||
}
|
||||
data = (unsigned short *)dmi->dmi_addr;
|
||||
outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR);
|
||||
outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i)));
|
||||
outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR);
|
||||
|
||||
@@ -194,7 +194,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
|
||||
|
||||
ret = of_address_to_resource(ofdev->node, 0, &res);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out_res;
|
||||
|
||||
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start);
|
||||
|
||||
@@ -236,6 +236,7 @@ out_free_irqs:
|
||||
kfree(new_bus->irq);
|
||||
out_unmap_regs:
|
||||
iounmap(fec->fecp);
|
||||
out_res:
|
||||
out_fec:
|
||||
kfree(fec);
|
||||
out_mii:
|
||||
|
||||
@@ -138,6 +138,7 @@ static int gfar_poll(struct napi_struct *napi, int budget);
|
||||
static void gfar_netpoll(struct net_device *dev);
|
||||
#endif
|
||||
int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
|
||||
static int gfar_clean_tx_ring(struct net_device *dev);
|
||||
static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
|
||||
static void gfar_vlan_rx_register(struct net_device *netdev,
|
||||
struct vlan_group *grp);
|
||||
@@ -1141,7 +1142,7 @@ static int gfar_close(struct net_device *dev)
|
||||
}
|
||||
|
||||
/* Changes the mac address if the controller is not running. */
|
||||
int gfar_set_mac_address(struct net_device *dev)
|
||||
static int gfar_set_mac_address(struct net_device *dev)
|
||||
{
|
||||
gfar_set_mac_for_addr(dev, 0, dev->dev_addr);
|
||||
|
||||
@@ -1260,7 +1261,7 @@ static void gfar_timeout(struct net_device *dev)
|
||||
}
|
||||
|
||||
/* Interrupt Handler for Transmit complete */
|
||||
int gfar_clean_tx_ring(struct net_device *dev)
|
||||
static int gfar_clean_tx_ring(struct net_device *dev)
|
||||
{
|
||||
struct txbd8 *bdp;
|
||||
struct gfar_private *priv = netdev_priv(dev);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user