diff options
-rw-r--r-- | drivers/net/ixp2000/enp2611.c | 13 | ||||
-rw-r--r-- | drivers/net/ixp2000/pm3386.c | 30 | ||||
-rw-r--r-- | drivers/net/ixp2000/pm3386.h | 1 | ||||
-rw-r--r-- | drivers/net/sky2.c | 13 |
4 files changed, 46 insertions, 11 deletions
diff --git a/drivers/net/ixp2000/enp2611.c b/drivers/net/ixp2000/enp2611.c index 6f7dce8eba5..b67f586d739 100644 --- a/drivers/net/ixp2000/enp2611.c +++ b/drivers/net/ixp2000/enp2611.c @@ -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; } diff --git a/drivers/net/ixp2000/pm3386.c b/drivers/net/ixp2000/pm3386.c index 5c7ab756405..5224651c9aa 100644 --- a/drivers/net/ixp2000/pm3386.c +++ b/drivers/net/ixp2000/pm3386.c @@ -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; diff --git a/drivers/net/ixp2000/pm3386.h b/drivers/net/ixp2000/pm3386.h index fe92bb056ac..cc4183dca91 100644 --- a/drivers/net/ixp2000/pm3386.h +++ b/drivers/net/ixp2000/pm3386.h @@ -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); diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index ffd267fab21..62be6d99d05 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -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); |