提交 96764898 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/netdev-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/netdev-2.6:
  sky2: prevent dual port receiver problems
  x86_64: Check for bad dma address in b44 1GB DMA workaround
  The ixp2000 driver for the enp2611 was developed on a board with
......@@ -149,6 +149,8 @@ static void enp2611_check_link_status(unsigned long __dummy)
int status;
dev = nds[i];
if (dev == NULL)
continue;
status = pm3386_is_link_up(i);
if (status && !netif_carrier_ok(dev)) {
......@@ -191,6 +193,7 @@ static void enp2611_set_port_admin_status(int port, int up)
static int __init enp2611_init_module(void)
{
int ports;
int i;
if (!machine_is_enp2611())
......@@ -199,7 +202,8 @@ static int __init enp2611_init_module(void)
caleb_reset();
pm3386_reset();
for (i = 0; i < 3; i++) {
ports = pm3386_port_count();
for (i = 0; i < ports; i++) {
nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv));
if (nds[i] == NULL) {
while (--i >= 0)
......@@ -215,9 +219,10 @@ static int __init enp2611_init_module(void)
ixp2400_msf_init(&enp2611_msf_parameters);
if (ixpdev_init(3, nds, enp2611_set_port_admin_status)) {
for (i = 0; i < 3; i++)
free_netdev(nds[i]);
if (ixpdev_init(ports, nds, enp2611_set_port_admin_status)) {
for (i = 0; i < ports; i++)
if (nds[i])
free_netdev(nds[i]);
return -EINVAL;
}
......
......@@ -86,40 +86,53 @@ static void pm3386_port_reg_write(int port, int _reg, int spacing, u16 value)
pm3386_reg_write(port >> 1, reg, value);
}
int pm3386_secondary_present(void)
{
return pm3386_reg_read(1, 0) == 0x3386;
}
void pm3386_reset(void)
{
u8 mac[3][6];
int secondary;
secondary = pm3386_secondary_present();
/* Save programmed MAC addresses. */
pm3386_get_mac(0, mac[0]);
pm3386_get_mac(1, mac[1]);
pm3386_get_mac(2, mac[2]);
if (secondary)
pm3386_get_mac(2, mac[2]);
/* Assert analog and digital reset. */
pm3386_reg_write(0, 0x002, 0x0060);
pm3386_reg_write(1, 0x002, 0x0060);
if (secondary)
pm3386_reg_write(1, 0x002, 0x0060);
mdelay(1);
/* Deassert analog reset. */
pm3386_reg_write(0, 0x002, 0x0062);
pm3386_reg_write(1, 0x002, 0x0062);
if (secondary)
pm3386_reg_write(1, 0x002, 0x0062);
mdelay(10);
/* Deassert digital reset. */
pm3386_reg_write(0, 0x002, 0x0063);
pm3386_reg_write(1, 0x002, 0x0063);
if (secondary)
pm3386_reg_write(1, 0x002, 0x0063);
mdelay(10);
/* Restore programmed MAC addresses. */
pm3386_set_mac(0, mac[0]);
pm3386_set_mac(1, mac[1]);
pm3386_set_mac(2, mac[2]);
if (secondary)
pm3386_set_mac(2, mac[2]);
/* Disable carrier on all ports. */
pm3386_set_carrier(0, 0);
pm3386_set_carrier(1, 0);
pm3386_set_carrier(2, 0);
if (secondary)
pm3386_set_carrier(2, 0);
}
static u16 swaph(u16 x)
......@@ -127,6 +140,11 @@ static u16 swaph(u16 x)
return ((x << 8) | (x >> 8)) & 0xffff;
}
int pm3386_port_count(void)
{
return 2 + pm3386_secondary_present();
}
void pm3386_init_port(int port)
{
int pm = port >> 1;
......
......@@ -13,6 +13,7 @@
#define __PM3386_H
void pm3386_reset(void);
int pm3386_port_count(void);
void pm3386_init_port(int port);
void pm3386_get_mac(int port, u8 *mac);
void pm3386_set_mac(int port, u8 *mac);
......
......@@ -1020,8 +1020,19 @@ static int sky2_up(struct net_device *dev)
struct sky2_hw *hw = sky2->hw;
unsigned port = sky2->port;
u32 ramsize, rxspace, imask;
int err = -ENOMEM;
int err;
struct net_device *otherdev = hw->dev[sky2->port^1];
/* Block bringing up both ports at the same time on a dual port card.
* There is an unfixed bug where receiver gets confused and picks up
* packets out of order. Until this is fixed, prevent data corruption.
*/
if (otherdev && netif_running(otherdev)) {
printk(KERN_INFO PFX "dual port support is disabled.\n");
return -EBUSY;
}
err = -ENOMEM;
if (netif_msg_ifup(sky2))
printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册