Merge branch 'upstream-davem' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
This commit is contained in:
commit
e62112c53a
|
@ -18,6 +18,7 @@
|
|||
#include <linux/timer.h>
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/pci.h>
|
||||
|
@ -69,6 +70,8 @@ static struct platform_device rd88f6281_nand_flash = {
|
|||
|
||||
static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
|
||||
.phy_addr = -1,
|
||||
.speed = SPEED_1000,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static struct mv_sata_platform_data rd88f6281_sata_data = {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/leds.h>
|
||||
|
@ -88,6 +89,8 @@ static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = {
|
|||
|
||||
static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
|
||||
.phy_addr = -1,
|
||||
.speed = SPEED_1000,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static void __init rd88f5181l_fxo_init(void)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/gpio.h>
|
||||
|
@ -89,6 +90,8 @@ static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = {
|
|||
|
||||
static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
|
||||
.phy_addr = -1,
|
||||
.speed = SPEED_1000,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
@ -92,6 +93,8 @@ static struct platform_device wnr854t_nor_flash = {
|
|||
|
||||
static struct mv643xx_eth_platform_data wnr854t_eth_data = {
|
||||
.phy_addr = -1,
|
||||
.speed = SPEED_1000,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static void __init wnr854t_init(void)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
@ -100,6 +101,8 @@ static struct platform_device wrt350n_v2_nor_flash = {
|
|||
|
||||
static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
|
||||
.phy_addr = -1,
|
||||
.speed = SPEED_1000,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static void __init wrt350n_v2_init(void)
|
||||
|
|
|
@ -510,14 +510,14 @@ config STNIC
|
|||
config SH_ETH
|
||||
tristate "Renesas SuperH Ethernet support"
|
||||
depends on SUPERH && \
|
||||
(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712)
|
||||
(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7763)
|
||||
select CRC32
|
||||
select MII
|
||||
select MDIO_BITBANG
|
||||
select PHYLIB
|
||||
help
|
||||
Renesas SuperH Ethernet device driver.
|
||||
This driver support SH7710 and SH7712.
|
||||
This driver support SH7710, SH7712 and SH7763.
|
||||
|
||||
config SUNLANCE
|
||||
tristate "Sun LANCE support"
|
||||
|
|
|
@ -605,36 +605,87 @@ adjust_head:
|
|||
static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
unsigned int data;
|
||||
u16 *data;
|
||||
|
||||
current_tx_ptr->skb = skb;
|
||||
|
||||
/*
|
||||
* Is skb->data always 16-bit aligned?
|
||||
* Do we need to memcpy((char *)(tail->packet + 2), skb->data, len)?
|
||||
*/
|
||||
if ((((unsigned int)(skb->data)) & 0x02) == 2) {
|
||||
/* move skb->data to current_tx_ptr payload */
|
||||
data = (unsigned int)(skb->data) - 2;
|
||||
*((unsigned short *)data) = (unsigned short)(skb->len);
|
||||
current_tx_ptr->desc_a.start_addr = (unsigned long)data;
|
||||
/* this is important! */
|
||||
blackfin_dcache_flush_range(data, (data + (skb->len)) + 2);
|
||||
|
||||
if (ANOMALY_05000285) {
|
||||
/*
|
||||
* TXDWA feature is not avaible to older revision < 0.3 silicon
|
||||
* of BF537
|
||||
*
|
||||
* Only if data buffer is ODD WORD alignment, we do not
|
||||
* need to memcpy
|
||||
*/
|
||||
u32 data_align = (u32)(skb->data) & 0x3;
|
||||
if (data_align == 0x2) {
|
||||
/* move skb->data to current_tx_ptr payload */
|
||||
data = (u16 *)(skb->data) - 1;
|
||||
*data = (u16)(skb->len);
|
||||
current_tx_ptr->desc_a.start_addr = (u32)data;
|
||||
/* this is important! */
|
||||
blackfin_dcache_flush_range((u32)data,
|
||||
(u32)((u8 *)data + skb->len + 4));
|
||||
} else {
|
||||
*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
|
||||
memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
|
||||
skb->len);
|
||||
current_tx_ptr->desc_a.start_addr =
|
||||
(u32)current_tx_ptr->packet;
|
||||
if (current_tx_ptr->status.status_word != 0)
|
||||
current_tx_ptr->status.status_word = 0;
|
||||
blackfin_dcache_flush_range(
|
||||
(u32)current_tx_ptr->packet,
|
||||
(u32)(current_tx_ptr->packet + skb->len + 2));
|
||||
}
|
||||
} else {
|
||||
*((unsigned short *)(current_tx_ptr->packet)) =
|
||||
(unsigned short)(skb->len);
|
||||
memcpy((char *)(current_tx_ptr->packet + 2), skb->data,
|
||||
(skb->len));
|
||||
current_tx_ptr->desc_a.start_addr =
|
||||
(unsigned long)current_tx_ptr->packet;
|
||||
if (current_tx_ptr->status.status_word != 0)
|
||||
current_tx_ptr->status.status_word = 0;
|
||||
blackfin_dcache_flush_range((unsigned int)current_tx_ptr->
|
||||
packet,
|
||||
(unsigned int)(current_tx_ptr->
|
||||
packet + skb->len) +
|
||||
2);
|
||||
/*
|
||||
* TXDWA feature is avaible to revision < 0.3 silicon of
|
||||
* BF537 and always avaible to BF52x
|
||||
*/
|
||||
u32 data_align = (u32)(skb->data) & 0x3;
|
||||
if (data_align == 0x0) {
|
||||
u16 sysctl = bfin_read_EMAC_SYSCTL();
|
||||
sysctl |= TXDWA;
|
||||
bfin_write_EMAC_SYSCTL(sysctl);
|
||||
|
||||
/* move skb->data to current_tx_ptr payload */
|
||||
data = (u16 *)(skb->data) - 2;
|
||||
*data = (u16)(skb->len);
|
||||
current_tx_ptr->desc_a.start_addr = (u32)data;
|
||||
/* this is important! */
|
||||
blackfin_dcache_flush_range(
|
||||
(u32)data,
|
||||
(u32)((u8 *)data + skb->len + 4));
|
||||
} else if (data_align == 0x2) {
|
||||
u16 sysctl = bfin_read_EMAC_SYSCTL();
|
||||
sysctl &= ~TXDWA;
|
||||
bfin_write_EMAC_SYSCTL(sysctl);
|
||||
|
||||
/* move skb->data to current_tx_ptr payload */
|
||||
data = (u16 *)(skb->data) - 1;
|
||||
*data = (u16)(skb->len);
|
||||
current_tx_ptr->desc_a.start_addr = (u32)data;
|
||||
/* this is important! */
|
||||
blackfin_dcache_flush_range(
|
||||
(u32)data,
|
||||
(u32)((u8 *)data + skb->len + 4));
|
||||
} else {
|
||||
u16 sysctl = bfin_read_EMAC_SYSCTL();
|
||||
sysctl &= ~TXDWA;
|
||||
bfin_write_EMAC_SYSCTL(sysctl);
|
||||
|
||||
*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
|
||||
memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
|
||||
skb->len);
|
||||
current_tx_ptr->desc_a.start_addr =
|
||||
(u32)current_tx_ptr->packet;
|
||||
if (current_tx_ptr->status.status_word != 0)
|
||||
current_tx_ptr->status.status_word = 0;
|
||||
blackfin_dcache_flush_range(
|
||||
(u32)current_tx_ptr->packet,
|
||||
(u32)(current_tx_ptr->packet + skb->len + 2));
|
||||
}
|
||||
}
|
||||
|
||||
/* enable this packet's dma */
|
||||
|
@ -691,7 +742,6 @@ static void bfin_mac_rx(struct net_device *dev)
|
|||
(unsigned long)skb->tail);
|
||||
|
||||
dev->last_rx = jiffies;
|
||||
skb->dev = dev;
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
#if defined(BFIN_MAC_CSUM_OFFLOAD)
|
||||
skb->csum = current_rx_ptr->status.ip_payload_csum;
|
||||
|
@ -920,6 +970,7 @@ static int bfin_mac_open(struct net_device *dev)
|
|||
phy_start(lp->phydev);
|
||||
phy_write(lp->phydev, MII_BMCR, BMCR_RESET);
|
||||
setup_system_regs(dev);
|
||||
setup_mac_addr(dev->dev_addr);
|
||||
bfin_mac_disable();
|
||||
bfin_mac_enable();
|
||||
pr_debug("hardware init finished\n");
|
||||
|
@ -955,7 +1006,7 @@ static int bfin_mac_close(struct net_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init bfin_mac_probe(struct platform_device *pdev)
|
||||
static int __devinit bfin_mac_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
struct bfin_mac_local *lp;
|
||||
|
@ -1081,7 +1132,7 @@ out_err_probe_mac:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int bfin_mac_remove(struct platform_device *pdev)
|
||||
static int __devexit bfin_mac_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct bfin_mac_local *lp = netdev_priv(ndev);
|
||||
|
@ -1128,7 +1179,7 @@ static int bfin_mac_resume(struct platform_device *pdev)
|
|||
|
||||
static struct platform_driver bfin_mac_driver = {
|
||||
.probe = bfin_mac_probe,
|
||||
.remove = bfin_mac_remove,
|
||||
.remove = __devexit_p(bfin_mac_remove),
|
||||
.resume = bfin_mac_resume,
|
||||
.suspend = bfin_mac_suspend,
|
||||
.driver = {
|
||||
|
|
|
@ -683,7 +683,7 @@ enum {
|
|||
SF_ERASE_SECTOR = 0xd8, /* erase sector */
|
||||
|
||||
FW_FLASH_BOOT_ADDR = 0x70000, /* start address of FW in flash */
|
||||
FW_VERS_ADDR = 0x77ffc, /* flash address holding FW version */
|
||||
FW_VERS_ADDR = 0x7fffc, /* flash address holding FW version */
|
||||
FW_MIN_SIZE = 8 /* at least version and csum */
|
||||
};
|
||||
|
||||
|
|
|
@ -2937,9 +2937,9 @@ static void ehea_rereg_mrs(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&dlpar_mem_lock);
|
||||
ehea_info("re-initializing driver complete");
|
||||
ehea_info("re-initializing driver complete");
|
||||
out:
|
||||
mutex_unlock(&dlpar_mem_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1547,8 +1547,10 @@ static int __devinit enc28j60_probe(struct spi_device *spi)
|
|||
random_ether_addr(dev->dev_addr);
|
||||
enc28j60_set_hw_macaddr(dev);
|
||||
|
||||
ret = request_irq(spi->irq, enc28j60_irq, IRQF_TRIGGER_FALLING,
|
||||
DRV_NAME, priv);
|
||||
/* Board setup must set the relevant edge trigger type;
|
||||
* level triggers won't currently work.
|
||||
*/
|
||||
ret = request_irq(spi->irq, enc28j60_irq, 0, DRV_NAME, priv);
|
||||
if (ret < 0) {
|
||||
if (netif_msg_probe(priv))
|
||||
dev_err(&spi->dev, DRV_NAME ": request irq %d failed "
|
||||
|
|
|
@ -333,6 +333,7 @@ enum {
|
|||
NvRegPowerState2 = 0x600,
|
||||
#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11
|
||||
#define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001
|
||||
#define NVREG_POWERSTATE2_PHY_RESET 0x0004
|
||||
};
|
||||
|
||||
/* Big endian: should work, but is untested */
|
||||
|
@ -529,6 +530,7 @@ union ring_type {
|
|||
#define PHY_REALTEK_INIT_REG4 0x14
|
||||
#define PHY_REALTEK_INIT_REG5 0x18
|
||||
#define PHY_REALTEK_INIT_REG6 0x11
|
||||
#define PHY_REALTEK_INIT_REG7 0x01
|
||||
#define PHY_REALTEK_INIT1 0x0000
|
||||
#define PHY_REALTEK_INIT2 0x8e00
|
||||
#define PHY_REALTEK_INIT3 0x0001
|
||||
|
@ -537,6 +539,9 @@ union ring_type {
|
|||
#define PHY_REALTEK_INIT6 0xf5c7
|
||||
#define PHY_REALTEK_INIT7 0x1000
|
||||
#define PHY_REALTEK_INIT8 0x0003
|
||||
#define PHY_REALTEK_INIT9 0x0008
|
||||
#define PHY_REALTEK_INIT10 0x0005
|
||||
#define PHY_REALTEK_INIT11 0x0200
|
||||
#define PHY_REALTEK_INIT_MSK1 0x0003
|
||||
|
||||
#define PHY_GIGABIT 0x0100
|
||||
|
@ -1149,6 +1154,42 @@ static int phy_init(struct net_device *dev)
|
|||
return PHY_ERROR;
|
||||
}
|
||||
}
|
||||
if (np->phy_model == PHY_MODEL_REALTEK_8211 &&
|
||||
np->phy_rev == PHY_REV_REALTEK_8211C) {
|
||||
u32 powerstate = readl(base + NvRegPowerState2);
|
||||
|
||||
/* need to perform hw phy reset */
|
||||
powerstate |= NVREG_POWERSTATE2_PHY_RESET;
|
||||
writel(powerstate, base + NvRegPowerState2);
|
||||
msleep(25);
|
||||
|
||||
powerstate &= ~NVREG_POWERSTATE2_PHY_RESET;
|
||||
writel(powerstate, base + NvRegPowerState2);
|
||||
msleep(25);
|
||||
|
||||
reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
|
||||
reg |= PHY_REALTEK_INIT9;
|
||||
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, reg)) {
|
||||
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
|
||||
return PHY_ERROR;
|
||||
}
|
||||
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT10)) {
|
||||
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
|
||||
return PHY_ERROR;
|
||||
}
|
||||
reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, MII_READ);
|
||||
if (!(reg & PHY_REALTEK_INIT11)) {
|
||||
reg |= PHY_REALTEK_INIT11;
|
||||
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, reg)) {
|
||||
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
|
||||
return PHY_ERROR;
|
||||
}
|
||||
}
|
||||
if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
|
||||
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
|
||||
return PHY_ERROR;
|
||||
}
|
||||
}
|
||||
if (np->phy_model == PHY_MODEL_REALTEK_8201) {
|
||||
if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
|
||||
np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
|
||||
|
@ -1201,12 +1242,23 @@ static int phy_init(struct net_device *dev)
|
|||
mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
|
||||
mii_control |= BMCR_ANENABLE;
|
||||
|
||||
/* reset the phy
|
||||
* (certain phys need bmcr to be setup with reset)
|
||||
*/
|
||||
if (phy_reset(dev, mii_control)) {
|
||||
printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev));
|
||||
return PHY_ERROR;
|
||||
if (np->phy_oui == PHY_OUI_REALTEK &&
|
||||
np->phy_model == PHY_MODEL_REALTEK_8211 &&
|
||||
np->phy_rev == PHY_REV_REALTEK_8211C) {
|
||||
/* start autoneg since we already performed hw reset above */
|
||||
mii_control |= BMCR_ANRESTART;
|
||||
if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) {
|
||||
printk(KERN_INFO "%s: phy init failed\n", pci_name(np->pci_dev));
|
||||
return PHY_ERROR;
|
||||
}
|
||||
} else {
|
||||
/* reset the phy
|
||||
* (certain phys need bmcr to be setup with reset)
|
||||
*/
|
||||
if (phy_reset(dev, mii_control)) {
|
||||
printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev));
|
||||
return PHY_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* phy vendor specific configuration */
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
#include <asm/system.h>
|
||||
|
||||
static char mv643xx_eth_driver_name[] = "mv643xx_eth";
|
||||
static char mv643xx_eth_driver_version[] = "1.1";
|
||||
static char mv643xx_eth_driver_version[] = "1.2";
|
||||
|
||||
#define MV643XX_ETH_CHECKSUM_OFFLOAD_TX
|
||||
#define MV643XX_ETH_NAPI
|
||||
|
@ -90,12 +90,21 @@ static char mv643xx_eth_driver_version[] = "1.1";
|
|||
#define PORT_SERIAL_CONTROL(p) (0x043c + ((p) << 10))
|
||||
#define PORT_STATUS(p) (0x0444 + ((p) << 10))
|
||||
#define TX_FIFO_EMPTY 0x00000400
|
||||
#define TX_IN_PROGRESS 0x00000080
|
||||
#define PORT_SPEED_MASK 0x00000030
|
||||
#define PORT_SPEED_1000 0x00000010
|
||||
#define PORT_SPEED_100 0x00000020
|
||||
#define PORT_SPEED_10 0x00000000
|
||||
#define FLOW_CONTROL_ENABLED 0x00000008
|
||||
#define FULL_DUPLEX 0x00000004
|
||||
#define LINK_UP 0x00000002
|
||||
#define TXQ_COMMAND(p) (0x0448 + ((p) << 10))
|
||||
#define TXQ_FIX_PRIO_CONF(p) (0x044c + ((p) << 10))
|
||||
#define TX_BW_RATE(p) (0x0450 + ((p) << 10))
|
||||
#define TX_BW_MTU(p) (0x0458 + ((p) << 10))
|
||||
#define TX_BW_BURST(p) (0x045c + ((p) << 10))
|
||||
#define INT_CAUSE(p) (0x0460 + ((p) << 10))
|
||||
#define INT_TX_END_0 0x00080000
|
||||
#define INT_TX_END 0x07f80000
|
||||
#define INT_RX 0x0007fbfc
|
||||
#define INT_EXT 0x00000002
|
||||
|
@ -127,21 +136,21 @@ static char mv643xx_eth_driver_version[] = "1.1";
|
|||
/*
|
||||
* SDMA configuration register.
|
||||
*/
|
||||
#define RX_BURST_SIZE_4_64BIT (2 << 1)
|
||||
#define RX_BURST_SIZE_16_64BIT (4 << 1)
|
||||
#define BLM_RX_NO_SWAP (1 << 4)
|
||||
#define BLM_TX_NO_SWAP (1 << 5)
|
||||
#define TX_BURST_SIZE_4_64BIT (2 << 22)
|
||||
#define TX_BURST_SIZE_16_64BIT (4 << 22)
|
||||
|
||||
#if defined(__BIG_ENDIAN)
|
||||
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
|
||||
RX_BURST_SIZE_4_64BIT | \
|
||||
TX_BURST_SIZE_4_64BIT
|
||||
RX_BURST_SIZE_16_64BIT | \
|
||||
TX_BURST_SIZE_16_64BIT
|
||||
#elif defined(__LITTLE_ENDIAN)
|
||||
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
|
||||
RX_BURST_SIZE_4_64BIT | \
|
||||
RX_BURST_SIZE_16_64BIT | \
|
||||
BLM_RX_NO_SWAP | \
|
||||
BLM_TX_NO_SWAP | \
|
||||
TX_BURST_SIZE_4_64BIT
|
||||
TX_BURST_SIZE_16_64BIT
|
||||
#else
|
||||
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
|
||||
#endif
|
||||
|
@ -153,9 +162,7 @@ static char mv643xx_eth_driver_version[] = "1.1";
|
|||
#define SET_MII_SPEED_TO_100 (1 << 24)
|
||||
#define SET_GMII_SPEED_TO_1000 (1 << 23)
|
||||
#define SET_FULL_DUPLEX_MODE (1 << 21)
|
||||
#define MAX_RX_PACKET_1522BYTE (1 << 17)
|
||||
#define MAX_RX_PACKET_9700BYTE (5 << 17)
|
||||
#define MAX_RX_PACKET_MASK (7 << 17)
|
||||
#define DISABLE_AUTO_NEG_SPEED_GMII (1 << 13)
|
||||
#define DO_NOT_FORCE_LINK_FAIL (1 << 10)
|
||||
#define SERIAL_PORT_CONTROL_RESERVED (1 << 9)
|
||||
|
@ -228,6 +235,8 @@ struct tx_desc {
|
|||
#define GEN_IP_V4_CHECKSUM 0x00040000
|
||||
#define GEN_TCP_UDP_CHECKSUM 0x00020000
|
||||
#define UDP_FRAME 0x00010000
|
||||
#define MAC_HDR_EXTRA_4_BYTES 0x00008000
|
||||
#define MAC_HDR_EXTRA_8_BYTES 0x00000200
|
||||
|
||||
#define TX_IHL_SHIFT 11
|
||||
|
||||
|
@ -404,6 +413,17 @@ static void rxq_disable(struct rx_queue *rxq)
|
|||
udelay(10);
|
||||
}
|
||||
|
||||
static void txq_reset_hw_ptr(struct tx_queue *txq)
|
||||
{
|
||||
struct mv643xx_eth_private *mp = txq_to_mp(txq);
|
||||
int off = TXQ_CURRENT_DESC_PTR(mp->port_num, txq->index);
|
||||
u32 addr;
|
||||
|
||||
addr = (u32)txq->tx_desc_dma;
|
||||
addr += txq->tx_curr_desc * sizeof(struct tx_desc);
|
||||
wrl(mp, off, addr);
|
||||
}
|
||||
|
||||
static void txq_enable(struct tx_queue *txq)
|
||||
{
|
||||
struct mv643xx_eth_private *mp = txq_to_mp(txq);
|
||||
|
@ -614,6 +634,12 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
|
|||
for (i = 0; i < 8; i++)
|
||||
if (mp->txq_mask & (1 << i))
|
||||
txq_reclaim(mp->txq + i, 0);
|
||||
|
||||
if (netif_carrier_ok(mp->dev)) {
|
||||
spin_lock(&mp->lock);
|
||||
__txq_maybe_wake(mp->txq + mp->txq_primary);
|
||||
spin_unlock(&mp->lock);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -706,6 +732,7 @@ static inline __be16 sum16_as_be(__sum16 sum)
|
|||
|
||||
static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
|
||||
{
|
||||
struct mv643xx_eth_private *mp = txq_to_mp(txq);
|
||||
int nr_frags = skb_shinfo(skb)->nr_frags;
|
||||
int tx_index;
|
||||
struct tx_desc *desc;
|
||||
|
@ -732,12 +759,36 @@ static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
|
|||
desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
BUG_ON(skb->protocol != htons(ETH_P_IP));
|
||||
int mac_hdr_len;
|
||||
|
||||
BUG_ON(skb->protocol != htons(ETH_P_IP) &&
|
||||
skb->protocol != htons(ETH_P_8021Q));
|
||||
|
||||
cmd_sts |= GEN_TCP_UDP_CHECKSUM |
|
||||
GEN_IP_V4_CHECKSUM |
|
||||
ip_hdr(skb)->ihl << TX_IHL_SHIFT;
|
||||
|
||||
mac_hdr_len = (void *)ip_hdr(skb) - (void *)skb->data;
|
||||
switch (mac_hdr_len - ETH_HLEN) {
|
||||
case 0:
|
||||
break;
|
||||
case 4:
|
||||
cmd_sts |= MAC_HDR_EXTRA_4_BYTES;
|
||||
break;
|
||||
case 8:
|
||||
cmd_sts |= MAC_HDR_EXTRA_8_BYTES;
|
||||
break;
|
||||
case 12:
|
||||
cmd_sts |= MAC_HDR_EXTRA_4_BYTES;
|
||||
cmd_sts |= MAC_HDR_EXTRA_8_BYTES;
|
||||
break;
|
||||
default:
|
||||
if (net_ratelimit())
|
||||
dev_printk(KERN_ERR, &txq_to_mp(txq)->dev->dev,
|
||||
"mac header length is %d?!\n", mac_hdr_len);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ip_hdr(skb)->protocol) {
|
||||
case IPPROTO_UDP:
|
||||
cmd_sts |= UDP_FRAME;
|
||||
|
@ -759,6 +810,10 @@ static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
|
|||
wmb();
|
||||
desc->cmd_sts = cmd_sts;
|
||||
|
||||
/* clear TX_END interrupt status */
|
||||
wrl(mp, INT_CAUSE(mp->port_num), ~(INT_TX_END_0 << txq->index));
|
||||
rdl(mp, INT_CAUSE(mp->port_num));
|
||||
|
||||
/* ensure all descriptors are written before poking hardware */
|
||||
wmb();
|
||||
txq_enable(txq);
|
||||
|
@ -1112,10 +1167,28 @@ static int mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *
|
|||
|
||||
static int mv643xx_eth_get_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct mv643xx_eth_private *mp = netdev_priv(dev);
|
||||
u32 port_status;
|
||||
|
||||
port_status = rdl(mp, PORT_STATUS(mp->port_num));
|
||||
|
||||
cmd->supported = SUPPORTED_MII;
|
||||
cmd->advertising = ADVERTISED_MII;
|
||||
cmd->speed = SPEED_1000;
|
||||
cmd->duplex = DUPLEX_FULL;
|
||||
switch (port_status & PORT_SPEED_MASK) {
|
||||
case PORT_SPEED_10:
|
||||
cmd->speed = SPEED_10;
|
||||
break;
|
||||
case PORT_SPEED_100:
|
||||
cmd->speed = SPEED_100;
|
||||
break;
|
||||
case PORT_SPEED_1000:
|
||||
cmd->speed = SPEED_1000;
|
||||
break;
|
||||
default:
|
||||
cmd->speed = -1;
|
||||
break;
|
||||
}
|
||||
cmd->duplex = (port_status & FULL_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF;
|
||||
cmd->port = PORT_MII;
|
||||
cmd->phy_address = 0;
|
||||
cmd->transceiver = XCVR_INTERNAL;
|
||||
|
@ -1539,8 +1612,11 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
|
|||
|
||||
tx_desc = (struct tx_desc *)txq->tx_desc_area;
|
||||
for (i = 0; i < txq->tx_ring_size; i++) {
|
||||
struct tx_desc *txd = tx_desc + i;
|
||||
int nexti = (i + 1) % txq->tx_ring_size;
|
||||
tx_desc[i].next_desc_ptr = txq->tx_desc_dma +
|
||||
|
||||
txd->cmd_sts = 0;
|
||||
txd->next_desc_ptr = txq->tx_desc_dma +
|
||||
nexti * sizeof(struct tx_desc);
|
||||
}
|
||||
|
||||
|
@ -1577,8 +1653,11 @@ static void txq_reclaim(struct tx_queue *txq, int force)
|
|||
desc = &txq->tx_desc_area[tx_index];
|
||||
cmd_sts = desc->cmd_sts;
|
||||
|
||||
if (!force && (cmd_sts & BUFFER_OWNED_BY_DMA))
|
||||
break;
|
||||
if (cmd_sts & BUFFER_OWNED_BY_DMA) {
|
||||
if (!force)
|
||||
break;
|
||||
desc->cmd_sts = cmd_sts & ~BUFFER_OWNED_BY_DMA;
|
||||
}
|
||||
|
||||
txq->tx_used_desc = (tx_index + 1) % txq->tx_ring_size;
|
||||
txq->tx_desc_count--;
|
||||
|
@ -1632,49 +1711,61 @@ static void txq_deinit(struct tx_queue *txq)
|
|||
|
||||
|
||||
/* netdev ops and related ***************************************************/
|
||||
static void update_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
|
||||
static void handle_link_event(struct mv643xx_eth_private *mp)
|
||||
{
|
||||
u32 pscr_o;
|
||||
u32 pscr_n;
|
||||
struct net_device *dev = mp->dev;
|
||||
u32 port_status;
|
||||
int speed;
|
||||
int duplex;
|
||||
int fc;
|
||||
|
||||
pscr_o = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
|
||||
|
||||
/* clear speed, duplex and rx buffer size fields */
|
||||
pscr_n = pscr_o & ~(SET_MII_SPEED_TO_100 |
|
||||
SET_GMII_SPEED_TO_1000 |
|
||||
SET_FULL_DUPLEX_MODE |
|
||||
MAX_RX_PACKET_MASK);
|
||||
|
||||
if (speed == SPEED_1000) {
|
||||
pscr_n |= SET_GMII_SPEED_TO_1000 | MAX_RX_PACKET_9700BYTE;
|
||||
} else {
|
||||
if (speed == SPEED_100)
|
||||
pscr_n |= SET_MII_SPEED_TO_100;
|
||||
pscr_n |= MAX_RX_PACKET_1522BYTE;
|
||||
}
|
||||
|
||||
if (duplex == DUPLEX_FULL)
|
||||
pscr_n |= SET_FULL_DUPLEX_MODE;
|
||||
|
||||
if (pscr_n != pscr_o) {
|
||||
if ((pscr_o & SERIAL_PORT_ENABLE) == 0)
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_n);
|
||||
else {
|
||||
port_status = rdl(mp, PORT_STATUS(mp->port_num));
|
||||
if (!(port_status & LINK_UP)) {
|
||||
if (netif_carrier_ok(dev)) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (mp->txq_mask & (1 << i))
|
||||
txq_disable(mp->txq + i);
|
||||
printk(KERN_INFO "%s: link down\n", dev->name);
|
||||
|
||||
pscr_o &= ~SERIAL_PORT_ENABLE;
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_o);
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_n);
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_n);
|
||||
netif_carrier_off(dev);
|
||||
netif_stop_queue(dev);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (mp->txq_mask & (1 << i))
|
||||
txq_enable(mp->txq + i);
|
||||
for (i = 0; i < 8; i++) {
|
||||
struct tx_queue *txq = mp->txq + i;
|
||||
|
||||
if (mp->txq_mask & (1 << i)) {
|
||||
txq_reclaim(txq, 1);
|
||||
txq_reset_hw_ptr(txq);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (port_status & PORT_SPEED_MASK) {
|
||||
case PORT_SPEED_10:
|
||||
speed = 10;
|
||||
break;
|
||||
case PORT_SPEED_100:
|
||||
speed = 100;
|
||||
break;
|
||||
case PORT_SPEED_1000:
|
||||
speed = 1000;
|
||||
break;
|
||||
default:
|
||||
speed = -1;
|
||||
break;
|
||||
}
|
||||
duplex = (port_status & FULL_DUPLEX) ? 1 : 0;
|
||||
fc = (port_status & FLOW_CONTROL_ENABLED) ? 1 : 0;
|
||||
|
||||
printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
|
||||
"flow control %sabled\n", dev->name,
|
||||
speed, duplex ? "full" : "half",
|
||||
fc ? "en" : "dis");
|
||||
|
||||
if (!netif_carrier_ok(dev)) {
|
||||
netif_carrier_on(dev);
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1684,7 +1775,6 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
|
|||
struct mv643xx_eth_private *mp = netdev_priv(dev);
|
||||
u32 int_cause;
|
||||
u32 int_cause_ext;
|
||||
u32 txq_active;
|
||||
|
||||
int_cause = rdl(mp, INT_CAUSE(mp->port_num)) &
|
||||
(INT_TX_END | INT_RX | INT_EXT);
|
||||
|
@ -1698,30 +1788,8 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
|
|||
wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext);
|
||||
}
|
||||
|
||||
if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) {
|
||||
if (mp->phy_addr == -1 || mii_link_ok(&mp->mii)) {
|
||||
int i;
|
||||
|
||||
if (mp->phy_addr != -1) {
|
||||
struct ethtool_cmd cmd;
|
||||
|
||||
mii_ethtool_gset(&mp->mii, &cmd);
|
||||
update_pscr(mp, cmd.speed, cmd.duplex);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (mp->txq_mask & (1 << i))
|
||||
txq_enable(mp->txq + i);
|
||||
|
||||
if (!netif_carrier_ok(dev)) {
|
||||
netif_carrier_on(dev);
|
||||
__txq_maybe_wake(mp->txq + mp->txq_primary);
|
||||
}
|
||||
} else if (netif_carrier_ok(dev)) {
|
||||
netif_stop_queue(dev);
|
||||
netif_carrier_off(dev);
|
||||
}
|
||||
}
|
||||
if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK))
|
||||
handle_link_event(mp);
|
||||
|
||||
/*
|
||||
* RxBuffer or RxError set for any of the 8 queues?
|
||||
|
@ -1743,8 +1811,6 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
|
|||
}
|
||||
#endif
|
||||
|
||||
txq_active = rdl(mp, TXQ_COMMAND(mp->port_num));
|
||||
|
||||
/*
|
||||
* TxBuffer or TxError set for any of the 8 queues?
|
||||
*/
|
||||
|
@ -1754,6 +1820,16 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
|
|||
for (i = 0; i < 8; i++)
|
||||
if (mp->txq_mask & (1 << i))
|
||||
txq_reclaim(mp->txq + i, 0);
|
||||
|
||||
/*
|
||||
* Enough space again in the primary TX queue for a
|
||||
* full packet?
|
||||
*/
|
||||
if (netif_carrier_ok(dev)) {
|
||||
spin_lock(&mp->lock);
|
||||
__txq_maybe_wake(mp->txq + mp->txq_primary);
|
||||
spin_unlock(&mp->lock);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1763,19 +1839,25 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
|
|||
int i;
|
||||
|
||||
wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_TX_END));
|
||||
|
||||
spin_lock(&mp->lock);
|
||||
for (i = 0; i < 8; i++) {
|
||||
struct tx_queue *txq = mp->txq + i;
|
||||
if (txq->tx_desc_count && !((txq_active >> i) & 1))
|
||||
u32 hw_desc_ptr;
|
||||
u32 expected_ptr;
|
||||
|
||||
if ((int_cause & (INT_TX_END_0 << i)) == 0)
|
||||
continue;
|
||||
|
||||
hw_desc_ptr =
|
||||
rdl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num, i));
|
||||
expected_ptr = (u32)txq->tx_desc_dma +
|
||||
txq->tx_curr_desc * sizeof(struct tx_desc);
|
||||
|
||||
if (hw_desc_ptr != expected_ptr)
|
||||
txq_enable(txq);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enough space again in the primary TX queue for a full packet?
|
||||
*/
|
||||
if (int_cause_ext & INT_EXT_TX) {
|
||||
struct tx_queue *txq = mp->txq + mp->txq_primary;
|
||||
__txq_maybe_wake(txq);
|
||||
spin_unlock(&mp->lock);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
@ -1785,14 +1867,14 @@ static void phy_reset(struct mv643xx_eth_private *mp)
|
|||
{
|
||||
unsigned int data;
|
||||
|
||||
smi_reg_read(mp, mp->phy_addr, 0, &data);
|
||||
data |= 0x8000;
|
||||
smi_reg_write(mp, mp->phy_addr, 0, data);
|
||||
smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);
|
||||
data |= BMCR_RESET;
|
||||
smi_reg_write(mp, mp->phy_addr, MII_BMCR, data);
|
||||
|
||||
do {
|
||||
udelay(1);
|
||||
smi_reg_read(mp, mp->phy_addr, 0, &data);
|
||||
} while (data & 0x8000);
|
||||
smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);
|
||||
} while (data & BMCR_RESET);
|
||||
}
|
||||
|
||||
static void port_start(struct mv643xx_eth_private *mp)
|
||||
|
@ -1800,23 +1882,6 @@ static void port_start(struct mv643xx_eth_private *mp)
|
|||
u32 pscr;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Configure basic link parameters.
|
||||
*/
|
||||
pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
|
||||
pscr &= ~(SERIAL_PORT_ENABLE | FORCE_LINK_PASS);
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
|
||||
pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
|
||||
DISABLE_AUTO_NEG_SPEED_GMII |
|
||||
DISABLE_AUTO_NEG_FOR_DUPLEX |
|
||||
DO_NOT_FORCE_LINK_FAIL |
|
||||
SERIAL_PORT_CONTROL_RESERVED;
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
|
||||
pscr |= SERIAL_PORT_ENABLE;
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
|
||||
|
||||
wrl(mp, SDMA_CONFIG(mp->port_num), PORT_SDMA_CONFIG_DEFAULT_VALUE);
|
||||
|
||||
/*
|
||||
* Perform PHY reset, if there is a PHY.
|
||||
*/
|
||||
|
@ -1828,22 +1893,32 @@ static void port_start(struct mv643xx_eth_private *mp)
|
|||
mv643xx_eth_set_settings(mp->dev, &cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure basic link parameters.
|
||||
*/
|
||||
pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
|
||||
|
||||
pscr |= SERIAL_PORT_ENABLE;
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
|
||||
|
||||
pscr |= DO_NOT_FORCE_LINK_FAIL;
|
||||
if (mp->phy_addr == -1)
|
||||
pscr |= FORCE_LINK_PASS;
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
|
||||
|
||||
wrl(mp, SDMA_CONFIG(mp->port_num), PORT_SDMA_CONFIG_DEFAULT_VALUE);
|
||||
|
||||
/*
|
||||
* Configure TX path and queues.
|
||||
*/
|
||||
tx_set_rate(mp, 1000000000, 16777216);
|
||||
for (i = 0; i < 8; i++) {
|
||||
struct tx_queue *txq = mp->txq + i;
|
||||
int off = TXQ_CURRENT_DESC_PTR(mp->port_num, i);
|
||||
u32 addr;
|
||||
|
||||
if ((mp->txq_mask & (1 << i)) == 0)
|
||||
continue;
|
||||
|
||||
addr = (u32)txq->tx_desc_dma;
|
||||
addr += txq->tx_curr_desc * sizeof(struct tx_desc);
|
||||
wrl(mp, off, addr);
|
||||
|
||||
txq_reset_hw_ptr(txq);
|
||||
txq_set_rate(txq, 1000000000, 16777216);
|
||||
txq_set_fixed_prio_mode(txq);
|
||||
}
|
||||
|
@ -1965,6 +2040,9 @@ static int mv643xx_eth_open(struct net_device *dev)
|
|||
napi_enable(&mp->napi);
|
||||
#endif
|
||||
|
||||
netif_carrier_off(dev);
|
||||
netif_stop_queue(dev);
|
||||
|
||||
port_start(mp);
|
||||
|
||||
set_rx_coal(mp, 0);
|
||||
|
@ -1999,8 +2077,14 @@ static void port_reset(struct mv643xx_eth_private *mp)
|
|||
if (mp->txq_mask & (1 << i))
|
||||
txq_disable(mp->txq + i);
|
||||
}
|
||||
while (!(rdl(mp, PORT_STATUS(mp->port_num)) & TX_FIFO_EMPTY))
|
||||
|
||||
while (1) {
|
||||
u32 ps = rdl(mp, PORT_STATUS(mp->port_num));
|
||||
|
||||
if ((ps & (TX_IN_PROGRESS | TX_FIFO_EMPTY)) == TX_FIFO_EMPTY)
|
||||
break;
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/* Reset the Enable bit in the Configuration Register */
|
||||
data = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
|
||||
|
@ -2202,7 +2286,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
|
|||
int ret;
|
||||
|
||||
if (!mv643xx_eth_version_printed++)
|
||||
printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n");
|
||||
printk(KERN_NOTICE "MV-643xx 10/100/1000 ethernet "
|
||||
"driver version %s\n", mv643xx_eth_driver_version);
|
||||
|
||||
ret = -EINVAL;
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
@ -2338,14 +2423,14 @@ static int phy_detect(struct mv643xx_eth_private *mp)
|
|||
unsigned int data;
|
||||
unsigned int data2;
|
||||
|
||||
smi_reg_read(mp, mp->phy_addr, 0, &data);
|
||||
smi_reg_write(mp, mp->phy_addr, 0, data ^ 0x1000);
|
||||
smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);
|
||||
smi_reg_write(mp, mp->phy_addr, MII_BMCR, data ^ BMCR_ANENABLE);
|
||||
|
||||
smi_reg_read(mp, mp->phy_addr, 0, &data2);
|
||||
if (((data ^ data2) & 0x1000) == 0)
|
||||
smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data2);
|
||||
if (((data ^ data2) & BMCR_ANENABLE) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
smi_reg_write(mp, mp->phy_addr, 0, data);
|
||||
smi_reg_write(mp, mp->phy_addr, MII_BMCR, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2393,12 +2478,39 @@ static int phy_init(struct mv643xx_eth_private *mp,
|
|||
cmd.duplex = pd->duplex;
|
||||
}
|
||||
|
||||
update_pscr(mp, cmd.speed, cmd.duplex);
|
||||
mv643xx_eth_set_settings(mp->dev, &cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
|
||||
{
|
||||
u32 pscr;
|
||||
|
||||
pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
|
||||
if (pscr & SERIAL_PORT_ENABLE) {
|
||||
pscr &= ~SERIAL_PORT_ENABLE;
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
|
||||
}
|
||||
|
||||
pscr = MAX_RX_PACKET_9700BYTE | SERIAL_PORT_CONTROL_RESERVED;
|
||||
if (mp->phy_addr == -1) {
|
||||
pscr |= DISABLE_AUTO_NEG_SPEED_GMII;
|
||||
if (speed == SPEED_1000)
|
||||
pscr |= SET_GMII_SPEED_TO_1000;
|
||||
else if (speed == SPEED_100)
|
||||
pscr |= SET_MII_SPEED_TO_100;
|
||||
|
||||
pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL;
|
||||
|
||||
pscr |= DISABLE_AUTO_NEG_FOR_DUPLEX;
|
||||
if (duplex == DUPLEX_FULL)
|
||||
pscr |= SET_FULL_DUPLEX_MODE;
|
||||
}
|
||||
|
||||
wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
|
||||
}
|
||||
|
||||
static int mv643xx_eth_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mv643xx_eth_platform_data *pd;
|
||||
|
@ -2452,6 +2564,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
|
|||
} else {
|
||||
SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless);
|
||||
}
|
||||
init_pscr(mp, pd->speed, pd->duplex);
|
||||
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
|
@ -2478,6 +2591,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
|
|||
* have to map the buffers to ISA memory which is only 16 MB
|
||||
*/
|
||||
dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
|
||||
dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM;
|
||||
#endif
|
||||
|
||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||
|
|
|
@ -536,7 +536,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
|
|||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
dev->poll_controller = eip_poll;
|
||||
#endif
|
||||
NS8390_init(dev, 0);
|
||||
NS8390p_init(dev, 0);
|
||||
|
||||
ret = register_netdev(dev);
|
||||
if (ret)
|
||||
|
@ -794,7 +794,7 @@ retry:
|
|||
if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */
|
||||
printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
|
||||
ne_reset_8390(dev);
|
||||
NS8390_init(dev,1);
|
||||
NS8390p_init(dev, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -855,7 +855,7 @@ static int ne_drv_resume(struct platform_device *pdev)
|
|||
|
||||
if (netif_running(dev)) {
|
||||
ne_reset_8390(dev);
|
||||
NS8390_init(dev, 1);
|
||||
NS8390p_init(dev, 1);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -3143,7 +3143,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
|
|||
pkt_cnt++;
|
||||
|
||||
/* Updating the statistics block */
|
||||
nic->stats.tx_bytes += skb->len;
|
||||
nic->dev->stats.tx_bytes += skb->len;
|
||||
nic->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
|
||||
dev_kfree_skb_irq(skb);
|
||||
|
||||
|
@ -4896,25 +4896,42 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
|
|||
/* Configure Stats for immediate updt */
|
||||
s2io_updt_stats(sp);
|
||||
|
||||
/* Using sp->stats as a staging area, because reset (due to mtu
|
||||
change, for example) will clear some hardware counters */
|
||||
dev->stats.tx_packets +=
|
||||
le32_to_cpu(mac_control->stats_info->tmac_frms) -
|
||||
sp->stats.tx_packets;
|
||||
sp->stats.tx_packets =
|
||||
le32_to_cpu(mac_control->stats_info->tmac_frms);
|
||||
dev->stats.tx_errors +=
|
||||
le32_to_cpu(mac_control->stats_info->tmac_any_err_frms) -
|
||||
sp->stats.tx_errors;
|
||||
sp->stats.tx_errors =
|
||||
le32_to_cpu(mac_control->stats_info->tmac_any_err_frms);
|
||||
dev->stats.rx_errors +=
|
||||
le64_to_cpu(mac_control->stats_info->rmac_drop_frms) -
|
||||
sp->stats.rx_errors;
|
||||
sp->stats.rx_errors =
|
||||
le64_to_cpu(mac_control->stats_info->rmac_drop_frms);
|
||||
dev->stats.multicast =
|
||||
le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms) -
|
||||
sp->stats.multicast;
|
||||
sp->stats.multicast =
|
||||
le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms);
|
||||
dev->stats.rx_length_errors =
|
||||
le64_to_cpu(mac_control->stats_info->rmac_long_frms) -
|
||||
sp->stats.rx_length_errors;
|
||||
sp->stats.rx_length_errors =
|
||||
le64_to_cpu(mac_control->stats_info->rmac_long_frms);
|
||||
|
||||
/* collect per-ring rx_packets and rx_bytes */
|
||||
sp->stats.rx_packets = sp->stats.rx_bytes = 0;
|
||||
dev->stats.rx_packets = dev->stats.rx_bytes = 0;
|
||||
for (i = 0; i < config->rx_ring_num; i++) {
|
||||
sp->stats.rx_packets += mac_control->rings[i].rx_packets;
|
||||
sp->stats.rx_bytes += mac_control->rings[i].rx_bytes;
|
||||
dev->stats.rx_packets += mac_control->rings[i].rx_packets;
|
||||
dev->stats.rx_bytes += mac_control->rings[i].rx_bytes;
|
||||
}
|
||||
|
||||
return (&sp->stats);
|
||||
return (&dev->stats);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7419,7 +7436,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
|
|||
if (err_mask != 0x5) {
|
||||
DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%x\n",
|
||||
dev->name, err_mask);
|
||||
sp->stats.rx_crc_errors++;
|
||||
dev->stats.rx_crc_errors++;
|
||||
sp->mac_control.stats_info->sw_stat.mem_freed
|
||||
+= skb->truesize;
|
||||
dev_kfree_skb(skb);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* SuperH Ethernet device driver
|
||||
*
|
||||
* Copyright (C) 2006,2007 Nobuhiro Iwamatsu
|
||||
* Copyright (C) 2006-2008 Nobuhiro Iwamatsu
|
||||
* Copyright (C) 2008 Renesas Solutions Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -143,13 +143,39 @@ static struct mdiobb_ops bb_ops = {
|
|||
.get_mdio_data = sh_get_mdio,
|
||||
};
|
||||
|
||||
/* Chip Reset */
|
||||
static void sh_eth_reset(struct net_device *ndev)
|
||||
{
|
||||
u32 ioaddr = ndev->base_addr;
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
int cnt = 100;
|
||||
|
||||
ctrl_outl(EDSR_ENALL, ioaddr + EDSR);
|
||||
ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
|
||||
while (cnt > 0) {
|
||||
if (!(ctrl_inl(ioaddr + EDMR) & 0x3))
|
||||
break;
|
||||
mdelay(1);
|
||||
cnt--;
|
||||
}
|
||||
if (cnt < 0)
|
||||
printk(KERN_ERR "Device reset fail\n");
|
||||
|
||||
/* Table Init */
|
||||
ctrl_outl(0x0, ioaddr + TDLAR);
|
||||
ctrl_outl(0x0, ioaddr + TDFAR);
|
||||
ctrl_outl(0x0, ioaddr + TDFXR);
|
||||
ctrl_outl(0x0, ioaddr + TDFFR);
|
||||
ctrl_outl(0x0, ioaddr + RDLAR);
|
||||
ctrl_outl(0x0, ioaddr + RDFAR);
|
||||
ctrl_outl(0x0, ioaddr + RDFXR);
|
||||
ctrl_outl(0x0, ioaddr + RDFFR);
|
||||
#else
|
||||
ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
|
||||
mdelay(3);
|
||||
ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* free skb and descriptor buffer */
|
||||
|
@ -180,6 +206,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
|
|||
/* format skb and descriptor buffer */
|
||||
static void sh_eth_ring_format(struct net_device *ndev)
|
||||
{
|
||||
u32 ioaddr = ndev->base_addr, reserve = 0;
|
||||
struct sh_eth_private *mdp = netdev_priv(ndev);
|
||||
int i;
|
||||
struct sk_buff *skb;
|
||||
|
@ -201,9 +228,15 @@ static void sh_eth_ring_format(struct net_device *ndev)
|
|||
mdp->rx_skbuff[i] = skb;
|
||||
if (skb == NULL)
|
||||
break;
|
||||
skb->dev = ndev; /* Mark as being used by this device. */
|
||||
skb->dev = ndev; /* Mark as being used by this device. */
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
reserve = SH7763_SKB_ALIGN
|
||||
- ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
|
||||
if (reserve)
|
||||
skb_reserve(skb, reserve);
|
||||
#else
|
||||
skb_reserve(skb, RX_OFFSET);
|
||||
|
||||
#endif
|
||||
/* RX descriptor */
|
||||
rxdesc = &mdp->rx_ring[i];
|
||||
rxdesc->addr = (u32)skb->data & ~0x3UL;
|
||||
|
@ -211,12 +244,25 @@ static void sh_eth_ring_format(struct net_device *ndev)
|
|||
|
||||
/* The size of the buffer is 16 byte boundary. */
|
||||
rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
|
||||
/* Rx descriptor address set */
|
||||
if (i == 0) {
|
||||
ctrl_outl((u32)rxdesc, ioaddr + RDLAR);
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
ctrl_outl((u32)rxdesc, ioaddr + RDFAR);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Rx descriptor address set */
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
ctrl_outl((u32)rxdesc, ioaddr + RDFXR);
|
||||
ctrl_outl(0x1, ioaddr + RDFFR);
|
||||
#endif
|
||||
|
||||
mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
|
||||
|
||||
/* Mark the last entry as wrapping the ring. */
|
||||
rxdesc->status |= cpu_to_le32(RC_RDEL);
|
||||
rxdesc->status |= cpu_to_le32(RD_RDEL);
|
||||
|
||||
memset(mdp->tx_ring, 0, tx_ringsize);
|
||||
|
||||
|
@ -226,8 +272,21 @@ static void sh_eth_ring_format(struct net_device *ndev)
|
|||
txdesc = &mdp->tx_ring[i];
|
||||
txdesc->status = cpu_to_le32(TD_TFP);
|
||||
txdesc->buffer_length = 0;
|
||||
if (i == 0) {
|
||||
/* Rx descriptor address set */
|
||||
ctrl_outl((u32)txdesc, ioaddr + TDLAR);
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
ctrl_outl((u32)txdesc, ioaddr + TDFAR);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Rx descriptor address set */
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
ctrl_outl((u32)txdesc, ioaddr + TDFXR);
|
||||
ctrl_outl(0x1, ioaddr + TDFFR);
|
||||
#endif
|
||||
|
||||
txdesc->status |= cpu_to_le32(TD_TDLE);
|
||||
}
|
||||
|
||||
|
@ -311,31 +370,43 @@ static int sh_eth_dev_init(struct net_device *ndev)
|
|||
/* Soft Reset */
|
||||
sh_eth_reset(ndev);
|
||||
|
||||
ctrl_outl(RPADIR_PADS1, ioaddr + RPADIR); /* SH7712-DMA-RX-PAD2 */
|
||||
/* Descriptor format */
|
||||
sh_eth_ring_format(ndev);
|
||||
ctrl_outl(RPADIR_INIT, ioaddr + RPADIR);
|
||||
|
||||
/* all sh_eth int mask */
|
||||
ctrl_outl(0, ioaddr + EESIPR);
|
||||
|
||||
/* FIFO size set */
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
ctrl_outl(EDMR_EL, ioaddr + EDMR);
|
||||
#else
|
||||
ctrl_outl(0, ioaddr + EDMR); /* Endian change */
|
||||
#endif
|
||||
|
||||
/* FIFO size set */
|
||||
ctrl_outl((FIFO_SIZE_T | FIFO_SIZE_R), ioaddr + FDR);
|
||||
ctrl_outl(0, ioaddr + TFTR);
|
||||
|
||||
/* Frame recv control */
|
||||
ctrl_outl(0, ioaddr + RMCR);
|
||||
|
||||
rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
|
||||
tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
|
||||
ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER);
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
/* Burst sycle set */
|
||||
ctrl_outl(0x800, ioaddr + BCULR);
|
||||
#endif
|
||||
|
||||
ctrl_outl((FIFO_F_D_RFF | FIFO_F_D_RFD), ioaddr + FCFTR);
|
||||
|
||||
#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
ctrl_outl(0, ioaddr + TRIMD);
|
||||
#endif
|
||||
|
||||
/* Descriptor format */
|
||||
sh_eth_ring_format(ndev);
|
||||
|
||||
ctrl_outl((u32)mdp->rx_ring, ioaddr + RDLAR);
|
||||
ctrl_outl((u32)mdp->tx_ring, ioaddr + TDLAR);
|
||||
/* Recv frame limit set register */
|
||||
ctrl_outl(RFLR_VALUE, ioaddr + RFLR);
|
||||
|
||||
ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR);
|
||||
ctrl_outl((DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff), ioaddr + EESIPR);
|
||||
|
@ -345,21 +416,26 @@ static int sh_eth_dev_init(struct net_device *ndev)
|
|||
ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;
|
||||
|
||||
ctrl_outl(val, ioaddr + ECMR);
|
||||
ctrl_outl(ECSR_BRCRX | ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD |
|
||||
ECSIPR_MPDIP, ioaddr + ECSR);
|
||||
ctrl_outl(ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP |
|
||||
ECSIPR_ICDIP | ECSIPR_MPDIP, ioaddr + ECSIPR);
|
||||
|
||||
/* E-MAC Status Register clear */
|
||||
ctrl_outl(ECSR_INIT, ioaddr + ECSR);
|
||||
|
||||
/* E-MAC Interrupt Enable register */
|
||||
ctrl_outl(ECSIPR_INIT, ioaddr + ECSIPR);
|
||||
|
||||
/* Set MAC address */
|
||||
update_mac_address(ndev);
|
||||
|
||||
/* mask reset */
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7710)
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
ctrl_outl(APR_AP, ioaddr + APR);
|
||||
ctrl_outl(MPR_MP, ioaddr + MPR);
|
||||
ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7710)
|
||||
ctrl_outl(BCFR_UNLIMITED, ioaddr + BCFR);
|
||||
#endif
|
||||
|
||||
/* Setting the Rx mode will start the Rx process. */
|
||||
ctrl_outl(EDRRR_R, ioaddr + EDRRR);
|
||||
|
||||
|
@ -407,7 +483,7 @@ static int sh_eth_rx(struct net_device *ndev)
|
|||
int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
|
||||
struct sk_buff *skb;
|
||||
u16 pkt_len = 0;
|
||||
u32 desc_status;
|
||||
u32 desc_status, reserve = 0;
|
||||
|
||||
rxdesc = &mdp->rx_ring[entry];
|
||||
while (!(rxdesc->status & cpu_to_le32(RD_RACT))) {
|
||||
|
@ -454,28 +530,38 @@ static int sh_eth_rx(struct net_device *ndev)
|
|||
for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
|
||||
entry = mdp->dirty_rx % RX_RING_SIZE;
|
||||
rxdesc = &mdp->rx_ring[entry];
|
||||
/* The size of the buffer is 16 byte boundary. */
|
||||
rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
|
||||
|
||||
if (mdp->rx_skbuff[entry] == NULL) {
|
||||
skb = dev_alloc_skb(mdp->rx_buf_sz);
|
||||
mdp->rx_skbuff[entry] = skb;
|
||||
if (skb == NULL)
|
||||
break; /* Better luck next round. */
|
||||
skb->dev = ndev;
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
reserve = SH7763_SKB_ALIGN
|
||||
- ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
|
||||
if (reserve)
|
||||
skb_reserve(skb, reserve);
|
||||
#else
|
||||
skb_reserve(skb, RX_OFFSET);
|
||||
#endif
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
rxdesc->addr = (u32)skb->data & ~0x3UL;
|
||||
}
|
||||
/* The size of the buffer is 16 byte boundary. */
|
||||
rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
|
||||
if (entry >= RX_RING_SIZE - 1)
|
||||
rxdesc->status |=
|
||||
cpu_to_le32(RD_RACT | RD_RFP | RC_RDEL);
|
||||
cpu_to_le32(RD_RACT | RD_RFP | RD_RDEL);
|
||||
else
|
||||
rxdesc->status |=
|
||||
cpu_to_le32(RD_RACT | RD_RFP);
|
||||
cpu_to_le32(RD_RACT | RD_RFP);
|
||||
}
|
||||
|
||||
/* Restart Rx engine if stopped. */
|
||||
/* If we don't need to check status, don't. -KDU */
|
||||
ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR);
|
||||
if (!(ctrl_inl(ndev->base_addr + EDRRR) & EDRRR_R))
|
||||
ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -529,13 +615,14 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
|
|||
printk(KERN_ERR "Receive Frame Overflow\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
if (intr_status & EESR_ADE) {
|
||||
if (intr_status & EESR_TDE) {
|
||||
if (intr_status & EESR_TFE)
|
||||
mdp->stats.tx_fifo_errors++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (intr_status & EESR_RDE) {
|
||||
/* Receive Descriptor Empty int */
|
||||
|
@ -550,8 +637,11 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
|
|||
mdp->stats.rx_fifo_errors++;
|
||||
printk(KERN_ERR "Receive FIFO Overflow\n");
|
||||
}
|
||||
if (intr_status &
|
||||
(EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE)) {
|
||||
if (intr_status & (EESR_TWB | EESR_TABT |
|
||||
#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
EESR_ADE |
|
||||
#endif
|
||||
EESR_TDE | EESR_TFE)) {
|
||||
/* Tx error */
|
||||
u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR);
|
||||
/* dmesg */
|
||||
|
@ -582,17 +672,23 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
|
|||
ioaddr = ndev->base_addr;
|
||||
spin_lock(&mdp->lock);
|
||||
|
||||
/* Get interrpt stat */
|
||||
intr_status = ctrl_inl(ioaddr + EESR);
|
||||
/* Clear interrupt */
|
||||
ctrl_outl(intr_status, ioaddr + EESR);
|
||||
|
||||
if (intr_status & (EESR_FRC | EESR_RINT8 |
|
||||
EESR_RINT5 | EESR_RINT4 | EESR_RINT3 | EESR_RINT2 |
|
||||
EESR_RINT1))
|
||||
if (intr_status & (EESR_FRC | /* Frame recv*/
|
||||
EESR_RMAF | /* Multi cast address recv*/
|
||||
EESR_RRF | /* Bit frame recv */
|
||||
EESR_RTLF | /* Long frame recv*/
|
||||
EESR_RTSF | /* short frame recv */
|
||||
EESR_PRE | /* PHY-LSI recv error */
|
||||
EESR_CERF)){ /* recv frame CRC error */
|
||||
sh_eth_rx(ndev);
|
||||
if (intr_status & (EESR_FTC |
|
||||
EESR_TINT4 | EESR_TINT3 | EESR_TINT2 | EESR_TINT1)) {
|
||||
}
|
||||
|
||||
/* Tx Check */
|
||||
if (intr_status & TX_CHECK) {
|
||||
sh_eth_txfree(ndev);
|
||||
netif_wake_queue(ndev);
|
||||
}
|
||||
|
@ -631,11 +727,32 @@ static void sh_eth_adjust_link(struct net_device *ndev)
|
|||
if (phydev->duplex != mdp->duplex) {
|
||||
new_state = 1;
|
||||
mdp->duplex = phydev->duplex;
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
if (mdp->duplex) { /* FULL */
|
||||
ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM,
|
||||
ioaddr + ECMR);
|
||||
} else { /* Half */
|
||||
ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM,
|
||||
ioaddr + ECMR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (phydev->speed != mdp->speed) {
|
||||
new_state = 1;
|
||||
mdp->speed = phydev->speed;
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
switch (mdp->speed) {
|
||||
case 10: /* 10BASE */
|
||||
ctrl_outl(GECMR_10, ioaddr + GECMR); break;
|
||||
case 100:/* 100BASE */
|
||||
ctrl_outl(GECMR_100, ioaddr + GECMR); break;
|
||||
case 1000: /* 1000BASE */
|
||||
ctrl_outl(GECMR_1000, ioaddr + GECMR); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (mdp->link == PHY_DOWN) {
|
||||
ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF)
|
||||
|
@ -730,7 +847,7 @@ static int sh_eth_open(struct net_device *ndev)
|
|||
/* Set the timer to check for link beat. */
|
||||
init_timer(&mdp->timer);
|
||||
mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
|
||||
setup_timer(&mdp->timer, sh_eth_timer, ndev);
|
||||
setup_timer(&mdp->timer, sh_eth_timer, (unsigned long)ndev);
|
||||
|
||||
return ret;
|
||||
|
||||
|
@ -820,7 +937,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
|||
|
||||
mdp->cur_tx++;
|
||||
|
||||
ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR);
|
||||
if (!(ctrl_inl(ndev->base_addr + EDTRR) & EDTRR_TRNS))
|
||||
ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR);
|
||||
|
||||
ndev->trans_start = jiffies;
|
||||
|
||||
return 0;
|
||||
|
@ -877,9 +996,15 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
|
|||
ctrl_outl(0, ioaddr + CDCR); /* (write clear) */
|
||||
mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + LCCR);
|
||||
ctrl_outl(0, ioaddr + LCCR); /* (write clear) */
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CERCR);/* CERCR */
|
||||
ctrl_outl(0, ioaddr + CERCR); /* (write clear) */
|
||||
mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CEECR);/* CEECR */
|
||||
ctrl_outl(0, ioaddr + CEECR); /* (write clear) */
|
||||
#else
|
||||
mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR);
|
||||
ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */
|
||||
|
||||
#endif
|
||||
return &mdp->stats;
|
||||
}
|
||||
|
||||
|
@ -929,8 +1054,13 @@ static void sh_eth_tsu_init(u32 ioaddr)
|
|||
ctrl_outl(0, ioaddr + TSU_FWSL0);
|
||||
ctrl_outl(0, ioaddr + TSU_FWSL1);
|
||||
ctrl_outl(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC);
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
ctrl_outl(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */
|
||||
ctrl_outl(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */
|
||||
#else
|
||||
ctrl_outl(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */
|
||||
ctrl_outl(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */
|
||||
#endif
|
||||
ctrl_outl(0, ioaddr + TSU_FWSR); /* all interrupt status clear */
|
||||
ctrl_outl(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */
|
||||
ctrl_outl(0, ioaddr + TSU_TEN); /* Disable all CAM entry */
|
||||
|
@ -1088,7 +1218,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
|
|||
/* First device only init */
|
||||
if (!devno) {
|
||||
/* reset device */
|
||||
ctrl_outl(ARSTR_ARSTR, ndev->base_addr + ARSTR);
|
||||
ctrl_outl(ARSTR_ARSTR, ARSTR);
|
||||
mdelay(1);
|
||||
|
||||
/* TSU init (Init only)*/
|
||||
|
@ -1110,8 +1240,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
|
|||
ndev->name, CARDNAME, (u32) ndev->base_addr);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
printk(KERN_INFO "%2.2x:", ndev->dev_addr[i]);
|
||||
printk(KERN_INFO "%2.2x, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);
|
||||
printk(KERN_INFO "%02X:", ndev->dev_addr[i]);
|
||||
printk(KERN_INFO "%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);
|
||||
|
||||
platform_set_drvdata(pdev, ndev);
|
||||
|
||||
|
|
|
@ -32,118 +32,249 @@
|
|||
|
||||
#define CARDNAME "sh-eth"
|
||||
#define TX_TIMEOUT (5*HZ)
|
||||
|
||||
#define TX_RING_SIZE 128 /* Tx ring size */
|
||||
#define RX_RING_SIZE 128 /* Rx ring size */
|
||||
#define RX_OFFSET 2 /* skb offset */
|
||||
#define TX_RING_SIZE 64 /* Tx ring size */
|
||||
#define RX_RING_SIZE 64 /* Rx ring size */
|
||||
#define ETHERSMALL 60
|
||||
#define PKT_BUF_SZ 1538
|
||||
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7763
|
||||
|
||||
#define SH7763_SKB_ALIGN 32
|
||||
/* Chip Base Address */
|
||||
#define SH_TSU_ADDR 0xA7000804
|
||||
# define SH_TSU_ADDR 0xFFE01800
|
||||
# define ARSTR 0xFFE01800
|
||||
|
||||
/* Chip Registers */
|
||||
/* E-DMAC */
|
||||
#define EDMR 0x0000
|
||||
#define EDTRR 0x0004
|
||||
#define EDRRR 0x0008
|
||||
#define TDLAR 0x000C
|
||||
#define RDLAR 0x0010
|
||||
#define EESR 0x0014
|
||||
#define EESIPR 0x0018
|
||||
#define TRSCER 0x001C
|
||||
#define RMFCR 0x0020
|
||||
#define TFTR 0x0024
|
||||
#define FDR 0x0028
|
||||
#define RMCR 0x002C
|
||||
#define EDOCR 0x0030
|
||||
#define FCFTR 0x0034
|
||||
#define RPADIR 0x0038
|
||||
#define TRIMD 0x003C
|
||||
#define RBWAR 0x0040
|
||||
#define RDFAR 0x0044
|
||||
#define TBRAR 0x004C
|
||||
#define TDFAR 0x0050
|
||||
/* Ether Register */
|
||||
#define ECMR 0x0160
|
||||
#define ECSR 0x0164
|
||||
#define ECSIPR 0x0168
|
||||
#define PIR 0x016C
|
||||
#define MAHR 0x0170
|
||||
#define MALR 0x0174
|
||||
#define RFLR 0x0178
|
||||
#define PSR 0x017C
|
||||
#define TROCR 0x0180
|
||||
#define CDCR 0x0184
|
||||
#define LCCR 0x0188
|
||||
#define CNDCR 0x018C
|
||||
#define CEFCR 0x0194
|
||||
#define FRECR 0x0198
|
||||
#define TSFRCR 0x019C
|
||||
#define TLFRCR 0x01A0
|
||||
#define RFCR 0x01A4
|
||||
#define MAFCR 0x01A8
|
||||
#define IPGR 0x01B4
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7710)
|
||||
#define APR 0x01B8
|
||||
#define MPR 0x01BC
|
||||
#define TPAUSER 0x1C4
|
||||
#define BCFR 0x1CC
|
||||
#endif /* CONFIG_CPU_SH7710 */
|
||||
# define EDSR 0x000
|
||||
# define EDMR 0x400
|
||||
# define EDTRR 0x408
|
||||
# define EDRRR 0x410
|
||||
# define EESR 0x428
|
||||
# define EESIPR 0x430
|
||||
# define TDLAR 0x010
|
||||
# define TDFAR 0x014
|
||||
# define TDFXR 0x018
|
||||
# define TDFFR 0x01C
|
||||
# define RDLAR 0x030
|
||||
# define RDFAR 0x034
|
||||
# define RDFXR 0x038
|
||||
# define RDFFR 0x03C
|
||||
# define TRSCER 0x438
|
||||
# define RMFCR 0x440
|
||||
# define TFTR 0x448
|
||||
# define FDR 0x450
|
||||
# define RMCR 0x458
|
||||
# define RPADIR 0x460
|
||||
# define FCFTR 0x468
|
||||
|
||||
#define ARSTR 0x0800
|
||||
/* Ether Register */
|
||||
# define ECMR 0x500
|
||||
# define ECSR 0x510
|
||||
# define ECSIPR 0x518
|
||||
# define PIR 0x520
|
||||
# define PSR 0x528
|
||||
# define PIPR 0x52C
|
||||
# define RFLR 0x508
|
||||
# define APR 0x554
|
||||
# define MPR 0x558
|
||||
# define PFTCR 0x55C
|
||||
# define PFRCR 0x560
|
||||
# define TPAUSER 0x564
|
||||
# define GECMR 0x5B0
|
||||
# define BCULR 0x5B4
|
||||
# define MAHR 0x5C0
|
||||
# define MALR 0x5C8
|
||||
# define TROCR 0x700
|
||||
# define CDCR 0x708
|
||||
# define LCCR 0x710
|
||||
# define CEFCR 0x740
|
||||
# define FRECR 0x748
|
||||
# define TSFRCR 0x750
|
||||
# define TLFRCR 0x758
|
||||
# define RFCR 0x760
|
||||
# define CERCR 0x768
|
||||
# define CEECR 0x770
|
||||
# define MAFCR 0x778
|
||||
|
||||
/* TSU Absolute Address */
|
||||
# define TSU_CTRST 0x004
|
||||
# define TSU_FWEN0 0x010
|
||||
# define TSU_FWEN1 0x014
|
||||
# define TSU_FCM 0x18
|
||||
# define TSU_BSYSL0 0x20
|
||||
# define TSU_BSYSL1 0x24
|
||||
# define TSU_PRISL0 0x28
|
||||
# define TSU_PRISL1 0x2C
|
||||
# define TSU_FWSL0 0x30
|
||||
# define TSU_FWSL1 0x34
|
||||
# define TSU_FWSLC 0x38
|
||||
# define TSU_QTAG0 0x40
|
||||
# define TSU_QTAG1 0x44
|
||||
# define TSU_FWSR 0x50
|
||||
# define TSU_FWINMK 0x54
|
||||
# define TSU_ADQT0 0x48
|
||||
# define TSU_ADQT1 0x4C
|
||||
# define TSU_VTAG0 0x58
|
||||
# define TSU_VTAG1 0x5C
|
||||
# define TSU_ADSBSY 0x60
|
||||
# define TSU_TEN 0x64
|
||||
# define TSU_POST1 0x70
|
||||
# define TSU_POST2 0x74
|
||||
# define TSU_POST3 0x78
|
||||
# define TSU_POST4 0x7C
|
||||
# define TSU_ADRH0 0x100
|
||||
# define TSU_ADRL0 0x104
|
||||
# define TSU_ADRH31 0x1F8
|
||||
# define TSU_ADRL31 0x1FC
|
||||
|
||||
# define TXNLCR0 0x80
|
||||
# define TXALCR0 0x84
|
||||
# define RXNLCR0 0x88
|
||||
# define RXALCR0 0x8C
|
||||
# define FWNLCR0 0x90
|
||||
# define FWALCR0 0x94
|
||||
# define TXNLCR1 0xA0
|
||||
# define TXALCR1 0xA4
|
||||
# define RXNLCR1 0xA8
|
||||
# define RXALCR1 0xAC
|
||||
# define FWNLCR1 0xB0
|
||||
# define FWALCR1 0x40
|
||||
|
||||
#else /* CONFIG_CPU_SUBTYPE_SH7763 */
|
||||
# define RX_OFFSET 2 /* skb offset */
|
||||
/* Chip base address */
|
||||
# define SH_TSU_ADDR 0xA7000804
|
||||
# define ARSTR 0xA7000800
|
||||
|
||||
/* Chip Registers */
|
||||
/* E-DMAC */
|
||||
# define EDMR 0x0000
|
||||
# define EDTRR 0x0004
|
||||
# define EDRRR 0x0008
|
||||
# define TDLAR 0x000C
|
||||
# define RDLAR 0x0010
|
||||
# define EESR 0x0014
|
||||
# define EESIPR 0x0018
|
||||
# define TRSCER 0x001C
|
||||
# define RMFCR 0x0020
|
||||
# define TFTR 0x0024
|
||||
# define FDR 0x0028
|
||||
# define RMCR 0x002C
|
||||
# define EDOCR 0x0030
|
||||
# define FCFTR 0x0034
|
||||
# define RPADIR 0x0038
|
||||
# define TRIMD 0x003C
|
||||
# define RBWAR 0x0040
|
||||
# define RDFAR 0x0044
|
||||
# define TBRAR 0x004C
|
||||
# define TDFAR 0x0050
|
||||
|
||||
/* Ether Register */
|
||||
# define ECMR 0x0160
|
||||
# define ECSR 0x0164
|
||||
# define ECSIPR 0x0168
|
||||
# define PIR 0x016C
|
||||
# define MAHR 0x0170
|
||||
# define MALR 0x0174
|
||||
# define RFLR 0x0178
|
||||
# define PSR 0x017C
|
||||
# define TROCR 0x0180
|
||||
# define CDCR 0x0184
|
||||
# define LCCR 0x0188
|
||||
# define CNDCR 0x018C
|
||||
# define CEFCR 0x0194
|
||||
# define FRECR 0x0198
|
||||
# define TSFRCR 0x019C
|
||||
# define TLFRCR 0x01A0
|
||||
# define RFCR 0x01A4
|
||||
# define MAFCR 0x01A8
|
||||
# define IPGR 0x01B4
|
||||
# if defined(CONFIG_CPU_SUBTYPE_SH7710)
|
||||
# define APR 0x01B8
|
||||
# define MPR 0x01BC
|
||||
# define TPAUSER 0x1C4
|
||||
# define BCFR 0x1CC
|
||||
# endif /* CONFIG_CPU_SH7710 */
|
||||
|
||||
/* TSU */
|
||||
#define TSU_CTRST 0x004
|
||||
#define TSU_FWEN0 0x010
|
||||
#define TSU_FWEN1 0x014
|
||||
#define TSU_FCM 0x018
|
||||
#define TSU_BSYSL0 0x020
|
||||
#define TSU_BSYSL1 0x024
|
||||
#define TSU_PRISL0 0x028
|
||||
#define TSU_PRISL1 0x02C
|
||||
#define TSU_FWSL0 0x030
|
||||
#define TSU_FWSL1 0x034
|
||||
#define TSU_FWSLC 0x038
|
||||
#define TSU_QTAGM0 0x040
|
||||
#define TSU_QTAGM1 0x044
|
||||
#define TSU_ADQT0 0x048
|
||||
#define TSU_ADQT1 0x04C
|
||||
#define TSU_FWSR 0x050
|
||||
#define TSU_FWINMK 0x054
|
||||
#define TSU_ADSBSY 0x060
|
||||
#define TSU_TEN 0x064
|
||||
#define TSU_POST1 0x070
|
||||
#define TSU_POST2 0x074
|
||||
#define TSU_POST3 0x078
|
||||
#define TSU_POST4 0x07C
|
||||
#define TXNLCR0 0x080
|
||||
#define TXALCR0 0x084
|
||||
#define RXNLCR0 0x088
|
||||
#define RXALCR0 0x08C
|
||||
#define FWNLCR0 0x090
|
||||
#define FWALCR0 0x094
|
||||
#define TXNLCR1 0x0A0
|
||||
#define TXALCR1 0x0A4
|
||||
#define RXNLCR1 0x0A8
|
||||
#define RXALCR1 0x0AC
|
||||
#define FWNLCR1 0x0B0
|
||||
#define FWALCR1 0x0B4
|
||||
# define TSU_CTRST 0x004
|
||||
# define TSU_FWEN0 0x010
|
||||
# define TSU_FWEN1 0x014
|
||||
# define TSU_FCM 0x018
|
||||
# define TSU_BSYSL0 0x020
|
||||
# define TSU_BSYSL1 0x024
|
||||
# define TSU_PRISL0 0x028
|
||||
# define TSU_PRISL1 0x02C
|
||||
# define TSU_FWSL0 0x030
|
||||
# define TSU_FWSL1 0x034
|
||||
# define TSU_FWSLC 0x038
|
||||
# define TSU_QTAGM0 0x040
|
||||
# define TSU_QTAGM1 0x044
|
||||
# define TSU_ADQT0 0x048
|
||||
# define TSU_ADQT1 0x04C
|
||||
# define TSU_FWSR 0x050
|
||||
# define TSU_FWINMK 0x054
|
||||
# define TSU_ADSBSY 0x060
|
||||
# define TSU_TEN 0x064
|
||||
# define TSU_POST1 0x070
|
||||
# define TSU_POST2 0x074
|
||||
# define TSU_POST3 0x078
|
||||
# define TSU_POST4 0x07C
|
||||
# define TXNLCR0 0x080
|
||||
# define TXALCR0 0x084
|
||||
# define RXNLCR0 0x088
|
||||
# define RXALCR0 0x08C
|
||||
# define FWNLCR0 0x090
|
||||
# define FWALCR0 0x094
|
||||
# define TXNLCR1 0x0A0
|
||||
# define TXALCR1 0x0A4
|
||||
# define RXNLCR1 0x0A8
|
||||
# define RXALCR1 0x0AC
|
||||
# define FWNLCR1 0x0B0
|
||||
# define FWALCR1 0x0B4
|
||||
|
||||
#define TSU_ADRH0 0x0100
|
||||
#define TSU_ADRL0 0x0104
|
||||
#define TSU_ADRL31 0x01FC
|
||||
|
||||
/* Register's bits */
|
||||
#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
|
||||
|
||||
/*
|
||||
* Register's bits
|
||||
*/
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7763
|
||||
/* EDSR */
|
||||
enum EDSR_BIT {
|
||||
EDSR_ENT = 0x01, EDSR_ENR = 0x02,
|
||||
};
|
||||
#define EDSR_ENALL (EDSR_ENT|EDSR_ENR)
|
||||
|
||||
/* GECMR */
|
||||
enum GECMR_BIT {
|
||||
GECMR_10 = 0x0, GECMR_100 = 0x04, GECMR_1000 = 0x01,
|
||||
};
|
||||
#endif
|
||||
|
||||
/* EDMR */
|
||||
enum DMAC_M_BIT {
|
||||
EDMR_DL1 = 0x20, EDMR_DL0 = 0x10, EDMR_SRST = 0x01,
|
||||
EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7763
|
||||
EDMR_SRST = 0x03,
|
||||
EMDR_DESC_R = 0x30, /* Descriptor reserve size */
|
||||
EDMR_EL = 0x40, /* Litte endian */
|
||||
#else /* CONFIG_CPU_SUBTYPE_SH7763 */
|
||||
EDMR_SRST = 0x01,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* EDTRR */
|
||||
enum DMAC_T_BIT {
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7763
|
||||
EDTRR_TRNS = 0x03,
|
||||
#else
|
||||
EDTRR_TRNS = 0x01,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* EDRRR*/
|
||||
|
@ -173,21 +304,47 @@ enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, };
|
|||
|
||||
/* EESR */
|
||||
enum EESR_BIT {
|
||||
EESR_TWB = 0x40000000, EESR_TABT = 0x04000000,
|
||||
#ifndef CONFIG_CPU_SUBTYPE_SH7763
|
||||
EESR_TWB = 0x40000000,
|
||||
#else
|
||||
EESR_TWB = 0xC0000000,
|
||||
EESR_TC1 = 0x20000000,
|
||||
EESR_TUC = 0x10000000,
|
||||
EESR_ROC = 0x80000000,
|
||||
#endif
|
||||
EESR_TABT = 0x04000000,
|
||||
EESR_RABT = 0x02000000, EESR_RFRMER = 0x01000000,
|
||||
EESR_ADE = 0x00800000, EESR_ECI = 0x00400000,
|
||||
EESR_FTC = 0x00200000, EESR_TDE = 0x00100000,
|
||||
EESR_TFE = 0x00080000, EESR_FRC = 0x00040000,
|
||||
EESR_RDE = 0x00020000, EESR_RFE = 0x00010000,
|
||||
EESR_TINT4 = 0x00000800, EESR_TINT3 = 0x00000400,
|
||||
EESR_TINT2 = 0x00000200, EESR_TINT1 = 0x00000100,
|
||||
EESR_RINT8 = 0x00000080, EESR_RINT5 = 0x00000010,
|
||||
EESR_RINT4 = 0x00000008, EESR_RINT3 = 0x00000004,
|
||||
EESR_RINT2 = 0x00000002, EESR_RINT1 = 0x00000001,
|
||||
#ifndef CONFIG_CPU_SUBTYPE_SH7763
|
||||
EESR_ADE = 0x00800000,
|
||||
#endif
|
||||
EESR_ECI = 0x00400000,
|
||||
EESR_FTC = 0x00200000, EESR_TDE = 0x00100000,
|
||||
EESR_TFE = 0x00080000, EESR_FRC = 0x00040000,
|
||||
EESR_RDE = 0x00020000, EESR_RFE = 0x00010000,
|
||||
#ifndef CONFIG_CPU_SUBTYPE_SH7763
|
||||
EESR_CND = 0x00000800,
|
||||
#endif
|
||||
EESR_DLC = 0x00000400,
|
||||
EESR_CD = 0x00000200, EESR_RTO = 0x00000100,
|
||||
EESR_RMAF = 0x00000080, EESR_CEEF = 0x00000040,
|
||||
EESR_CELF = 0x00000020, EESR_RRF = 0x00000010,
|
||||
EESR_RTLF = 0x00000008, EESR_RTSF = 0x00000004,
|
||||
EESR_PRE = 0x00000002, EESR_CERF = 0x00000001,
|
||||
};
|
||||
|
||||
#define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
|
||||
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7763
|
||||
# define TX_CHECK (EESR_TC1 | EESR_FTC)
|
||||
# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
|
||||
| EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI)
|
||||
# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE)
|
||||
|
||||
#else
|
||||
# define TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO)
|
||||
# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
|
||||
| EESR_RFRMER | EESR_ADE | EESR_TFE | EESR_TDE | EESR_ECI)
|
||||
# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE)
|
||||
#endif
|
||||
|
||||
/* EESIPR */
|
||||
enum DMAC_IM_BIT {
|
||||
|
@ -207,8 +364,8 @@ enum DMAC_IM_BIT {
|
|||
|
||||
/* Receive descriptor bit */
|
||||
enum RD_STS_BIT {
|
||||
RD_RACT = 0x80000000, RC_RDEL = 0x40000000,
|
||||
RC_RFP1 = 0x20000000, RC_RFP0 = 0x10000000,
|
||||
RD_RACT = 0x80000000, RD_RDEL = 0x40000000,
|
||||
RD_RFP1 = 0x20000000, RD_RFP0 = 0x10000000,
|
||||
RD_RFE = 0x08000000, RD_RFS10 = 0x00000200,
|
||||
RD_RFS9 = 0x00000100, RD_RFS8 = 0x00000080,
|
||||
RD_RFS7 = 0x00000040, RD_RFS6 = 0x00000020,
|
||||
|
@ -216,9 +373,9 @@ enum RD_STS_BIT {
|
|||
RD_RFS3 = 0x00000004, RD_RFS2 = 0x00000002,
|
||||
RD_RFS1 = 0x00000001,
|
||||
};
|
||||
#define RDF1ST RC_RFP1
|
||||
#define RDFEND RC_RFP0
|
||||
#define RD_RFP (RC_RFP1|RC_RFP0)
|
||||
#define RDF1ST RD_RFP1
|
||||
#define RDFEND RD_RFP0
|
||||
#define RD_RFP (RD_RFP1|RD_RFP0)
|
||||
|
||||
/* FCFTR */
|
||||
enum FCFTR_BIT {
|
||||
|
@ -231,7 +388,8 @@ enum FCFTR_BIT {
|
|||
|
||||
/* Transfer descriptor bit */
|
||||
enum TD_STS_BIT {
|
||||
TD_TACT = 0x80000000, TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000,
|
||||
TD_TACT = 0x80000000,
|
||||
TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000,
|
||||
TD_TFP0 = 0x10000000,
|
||||
};
|
||||
#define TDF1ST TD_TFP1
|
||||
|
@ -242,6 +400,10 @@ enum TD_STS_BIT {
|
|||
enum RECV_RST_BIT { RMCR_RST = 0x01, };
|
||||
/* ECMR */
|
||||
enum FELIC_MODE_BIT {
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7763
|
||||
ECMR_TRCCM = 0x04000000, ECMR_RCSC = 0x00800000,
|
||||
ECMR_DPAD = 0x00200000, ECMR_RZPF = 0x00100000,
|
||||
#endif
|
||||
ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000,
|
||||
ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000,
|
||||
ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020,
|
||||
|
@ -249,18 +411,45 @@ enum FELIC_MODE_BIT {
|
|||
ECMR_PRM = 0x00000001,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7763
|
||||
#define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF |\
|
||||
ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
|
||||
#else
|
||||
#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR ECMR_RXF | ECMR_TXF | ECMR_MCT)
|
||||
#endif
|
||||
|
||||
/* ECSR */
|
||||
enum ECSR_STATUS_BIT {
|
||||
ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10, ECSR_LCHNG = 0x04,
|
||||
#ifndef CONFIG_CPU_SUBTYPE_SH7763
|
||||
ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10,
|
||||
#endif
|
||||
ECSR_LCHNG = 0x04,
|
||||
ECSR_MPD = 0x02, ECSR_ICD = 0x01,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7763
|
||||
# define ECSR_INIT (ECSR_ICD | ECSIPR_MPDIP)
|
||||
#else
|
||||
# define ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | \
|
||||
ECSR_LCHNG | ECSR_ICD | ECSIPR_MPDIP)
|
||||
#endif
|
||||
|
||||
/* ECSIPR */
|
||||
enum ECSIPR_STATUS_MASK_BIT {
|
||||
ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10, ECSIPR_LCHNGIP = 0x04,
|
||||
#ifndef CONFIG_CPU_SUBTYPE_SH7763
|
||||
ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10,
|
||||
#endif
|
||||
ECSIPR_LCHNGIP = 0x04,
|
||||
ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7763
|
||||
# define ECSIPR_INIT (ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
|
||||
#else
|
||||
# define ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | \
|
||||
ECSIPR_ICDIP | ECSIPR_MPDIP)
|
||||
#endif
|
||||
|
||||
/* APR */
|
||||
enum APR_BIT {
|
||||
APR_AP = 0x00000001,
|
||||
|
@ -285,6 +474,15 @@ enum RPADIR_BIT {
|
|||
RPADIR_PADR = 0x0003f,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
|
||||
# define RPADIR_INIT (0x00)
|
||||
#else
|
||||
# define RPADIR_INIT (RPADIR_PADS1)
|
||||
#endif
|
||||
|
||||
/* RFLR */
|
||||
#define RFLR_VALUE 0x1000
|
||||
|
||||
/* FDR */
|
||||
enum FIFO_SIZE_BIT {
|
||||
FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007,
|
||||
|
@ -316,7 +514,7 @@ enum PHY_ANA_BIT {
|
|||
PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000,
|
||||
PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100,
|
||||
PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020,
|
||||
PHY_A_SEL = 0x001f,
|
||||
PHY_A_SEL = 0x001e,
|
||||
};
|
||||
/* PHY_ANL */
|
||||
enum PHY_ANL_BIT {
|
||||
|
@ -449,6 +647,10 @@ struct sh_eth_private {
|
|||
struct net_device_stats tsu_stats; /* TSU forward status */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7763
|
||||
/* SH7763 has endian control register */
|
||||
#define swaps(x, y)
|
||||
#else
|
||||
static void swaps(char *src, int len)
|
||||
{
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
|
@ -460,5 +662,5 @@ static void swaps(char *src, int len)
|
|||
*p = swab32(*p);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
|
||||
#endif
|
||||
|
|
|
@ -55,12 +55,28 @@
|
|||
|
||||
static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
|
||||
{
|
||||
void *buf;
|
||||
int err = -ENOMEM;
|
||||
|
||||
devdbg(dev, "dm_read() reg=0x%02x length=%d", reg, length);
|
||||
return usb_control_msg(dev->udev,
|
||||
usb_rcvctrlpipe(dev->udev, 0),
|
||||
DM_READ_REGS,
|
||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
0, reg, data, length, USB_CTRL_SET_TIMEOUT);
|
||||
|
||||
buf = kmalloc(length, GFP_KERNEL);
|
||||
if (!buf)
|
||||
goto out;
|
||||
|
||||
err = usb_control_msg(dev->udev,
|
||||
usb_rcvctrlpipe(dev->udev, 0),
|
||||
DM_READ_REGS,
|
||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
0, reg, buf, length, USB_CTRL_SET_TIMEOUT);
|
||||
if (err == length)
|
||||
memcpy(data, buf, length);
|
||||
else if (err >= 0)
|
||||
err = -EINVAL;
|
||||
kfree(buf);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value)
|
||||
|
@ -70,12 +86,28 @@ static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value)
|
|||
|
||||
static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
|
||||
{
|
||||
void *buf = NULL;
|
||||
int err = -ENOMEM;
|
||||
|
||||
devdbg(dev, "dm_write() reg=0x%02x, length=%d", reg, length);
|
||||
return usb_control_msg(dev->udev,
|
||||
usb_sndctrlpipe(dev->udev, 0),
|
||||
DM_WRITE_REGS,
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
|
||||
0, reg, data, length, USB_CTRL_SET_TIMEOUT);
|
||||
|
||||
if (data) {
|
||||
buf = kmalloc(length, GFP_KERNEL);
|
||||
if (!buf)
|
||||
goto out;
|
||||
memcpy(buf, data, length);
|
||||
}
|
||||
|
||||
err = usb_control_msg(dev->udev,
|
||||
usb_sndctrlpipe(dev->udev, 0),
|
||||
DM_WRITE_REGS,
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
|
||||
0, reg, buf, length, USB_CTRL_SET_TIMEOUT);
|
||||
kfree(buf);
|
||||
if (err >= 0 && err < length)
|
||||
err = -EINVAL;
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
|
||||
|
|
|
@ -337,7 +337,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
|
|||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
dev->poll_controller = ei_poll;
|
||||
#endif
|
||||
NS8390_init(dev, 0);
|
||||
NS8390p_init(dev, 0);
|
||||
|
||||
#if 1
|
||||
/* Enable interrupt generation on softconfig cards -- M.U */
|
||||
|
|
Loading…
Reference in New Issue