mirror of https://gitee.com/openkylin/linux.git
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
This commit is contained in:
commit
9676489866
|
@ -149,6 +149,8 @@ static void enp2611_check_link_status(unsigned long __dummy)
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
dev = nds[i];
|
dev = nds[i];
|
||||||
|
if (dev == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
status = pm3386_is_link_up(i);
|
status = pm3386_is_link_up(i);
|
||||||
if (status && !netif_carrier_ok(dev)) {
|
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)
|
static int __init enp2611_init_module(void)
|
||||||
{
|
{
|
||||||
|
int ports;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!machine_is_enp2611())
|
if (!machine_is_enp2611())
|
||||||
|
@ -199,7 +202,8 @@ static int __init enp2611_init_module(void)
|
||||||
caleb_reset();
|
caleb_reset();
|
||||||
pm3386_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));
|
nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv));
|
||||||
if (nds[i] == NULL) {
|
if (nds[i] == NULL) {
|
||||||
while (--i >= 0)
|
while (--i >= 0)
|
||||||
|
@ -215,9 +219,10 @@ static int __init enp2611_init_module(void)
|
||||||
|
|
||||||
ixp2400_msf_init(&enp2611_msf_parameters);
|
ixp2400_msf_init(&enp2611_msf_parameters);
|
||||||
|
|
||||||
if (ixpdev_init(3, nds, enp2611_set_port_admin_status)) {
|
if (ixpdev_init(ports, nds, enp2611_set_port_admin_status)) {
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < ports; i++)
|
||||||
free_netdev(nds[i]);
|
if (nds[i])
|
||||||
|
free_netdev(nds[i]);
|
||||||
return -EINVAL;
|
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);
|
pm3386_reg_write(port >> 1, reg, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pm3386_secondary_present(void)
|
||||||
|
{
|
||||||
|
return pm3386_reg_read(1, 0) == 0x3386;
|
||||||
|
}
|
||||||
|
|
||||||
void pm3386_reset(void)
|
void pm3386_reset(void)
|
||||||
{
|
{
|
||||||
u8 mac[3][6];
|
u8 mac[3][6];
|
||||||
|
int secondary;
|
||||||
|
|
||||||
|
secondary = pm3386_secondary_present();
|
||||||
|
|
||||||
/* Save programmed MAC addresses. */
|
/* Save programmed MAC addresses. */
|
||||||
pm3386_get_mac(0, mac[0]);
|
pm3386_get_mac(0, mac[0]);
|
||||||
pm3386_get_mac(1, mac[1]);
|
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. */
|
/* Assert analog and digital reset. */
|
||||||
pm3386_reg_write(0, 0x002, 0x0060);
|
pm3386_reg_write(0, 0x002, 0x0060);
|
||||||
pm3386_reg_write(1, 0x002, 0x0060);
|
if (secondary)
|
||||||
|
pm3386_reg_write(1, 0x002, 0x0060);
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
|
|
||||||
/* Deassert analog reset. */
|
/* Deassert analog reset. */
|
||||||
pm3386_reg_write(0, 0x002, 0x0062);
|
pm3386_reg_write(0, 0x002, 0x0062);
|
||||||
pm3386_reg_write(1, 0x002, 0x0062);
|
if (secondary)
|
||||||
|
pm3386_reg_write(1, 0x002, 0x0062);
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
|
|
||||||
/* Deassert digital reset. */
|
/* Deassert digital reset. */
|
||||||
pm3386_reg_write(0, 0x002, 0x0063);
|
pm3386_reg_write(0, 0x002, 0x0063);
|
||||||
pm3386_reg_write(1, 0x002, 0x0063);
|
if (secondary)
|
||||||
|
pm3386_reg_write(1, 0x002, 0x0063);
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
|
|
||||||
/* Restore programmed MAC addresses. */
|
/* Restore programmed MAC addresses. */
|
||||||
pm3386_set_mac(0, mac[0]);
|
pm3386_set_mac(0, mac[0]);
|
||||||
pm3386_set_mac(1, mac[1]);
|
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. */
|
/* Disable carrier on all ports. */
|
||||||
pm3386_set_carrier(0, 0);
|
pm3386_set_carrier(0, 0);
|
||||||
pm3386_set_carrier(1, 0);
|
pm3386_set_carrier(1, 0);
|
||||||
pm3386_set_carrier(2, 0);
|
if (secondary)
|
||||||
|
pm3386_set_carrier(2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u16 swaph(u16 x)
|
static u16 swaph(u16 x)
|
||||||
|
@ -127,6 +140,11 @@ static u16 swaph(u16 x)
|
||||||
return ((x << 8) | (x >> 8)) & 0xffff;
|
return ((x << 8) | (x >> 8)) & 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pm3386_port_count(void)
|
||||||
|
{
|
||||||
|
return 2 + pm3386_secondary_present();
|
||||||
|
}
|
||||||
|
|
||||||
void pm3386_init_port(int port)
|
void pm3386_init_port(int port)
|
||||||
{
|
{
|
||||||
int pm = port >> 1;
|
int pm = port >> 1;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define __PM3386_H
|
#define __PM3386_H
|
||||||
|
|
||||||
void pm3386_reset(void);
|
void pm3386_reset(void);
|
||||||
|
int pm3386_port_count(void);
|
||||||
void pm3386_init_port(int port);
|
void pm3386_init_port(int port);
|
||||||
void pm3386_get_mac(int port, u8 *mac);
|
void pm3386_get_mac(int port, u8 *mac);
|
||||||
void pm3386_set_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;
|
struct sky2_hw *hw = sky2->hw;
|
||||||
unsigned port = sky2->port;
|
unsigned port = sky2->port;
|
||||||
u32 ramsize, rxspace, imask;
|
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))
|
if (netif_msg_ifup(sky2))
|
||||||
printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
|
printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue