mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 17:12:06 +00:00
[PATCH] mv643xx_eth: use MII library for ethtool functions
Use the common ethtool support functions of the MII library. Add generic MII ioctl handler. Add PHY parameter speed/duplex/negotiation initialization and modification. Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: Dale Farnsworth <dale@farnsworth.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
This commit is contained in:
parent
c28a4f8947
commit
d0412d9670
@ -101,6 +101,7 @@ static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
|
||||
static int ethernet_phy_detect(unsigned int eth_port_num);
|
||||
static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location);
|
||||
static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val);
|
||||
static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
|
||||
static struct ethtool_ops mv643xx_ethtool_ops;
|
||||
|
||||
static char mv643xx_driver_name[] = "mv643xx_eth";
|
||||
@ -457,6 +458,56 @@ static int mv643xx_eth_receive_queue(struct net_device *dev)
|
||||
return received_packets;
|
||||
}
|
||||
|
||||
/* Set the mv643xx port configuration register for the speed/duplex mode. */
|
||||
static void mv643xx_eth_update_pscr(struct net_device *dev,
|
||||
struct ethtool_cmd *ecmd)
|
||||
{
|
||||
struct mv643xx_private *mp = netdev_priv(dev);
|
||||
int port_num = mp->port_num;
|
||||
u32 o_pscr, n_pscr;
|
||||
unsigned int channels;
|
||||
|
||||
o_pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
|
||||
n_pscr = o_pscr;
|
||||
|
||||
/* clear speed, duplex and rx buffer size fields */
|
||||
n_pscr &= ~(MV643XX_ETH_SET_MII_SPEED_TO_100 |
|
||||
MV643XX_ETH_SET_GMII_SPEED_TO_1000 |
|
||||
MV643XX_ETH_SET_FULL_DUPLEX_MODE |
|
||||
MV643XX_ETH_MAX_RX_PACKET_MASK);
|
||||
|
||||
if (ecmd->duplex == DUPLEX_FULL)
|
||||
n_pscr |= MV643XX_ETH_SET_FULL_DUPLEX_MODE;
|
||||
|
||||
if (ecmd->speed == SPEED_1000)
|
||||
n_pscr |= MV643XX_ETH_SET_GMII_SPEED_TO_1000 |
|
||||
MV643XX_ETH_MAX_RX_PACKET_9700BYTE;
|
||||
else {
|
||||
if (ecmd->speed == SPEED_100)
|
||||
n_pscr |= MV643XX_ETH_SET_MII_SPEED_TO_100;
|
||||
n_pscr |= MV643XX_ETH_MAX_RX_PACKET_1522BYTE;
|
||||
}
|
||||
|
||||
if (n_pscr != o_pscr) {
|
||||
if ((o_pscr & MV643XX_ETH_SERIAL_PORT_ENABLE) == 0)
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
|
||||
n_pscr);
|
||||
else {
|
||||
channels = mv643xx_eth_port_disable_tx(port_num);
|
||||
|
||||
o_pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE;
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
|
||||
o_pscr);
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
|
||||
n_pscr);
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
|
||||
n_pscr);
|
||||
if (channels)
|
||||
mv643xx_eth_port_enable_tx(port_num, channels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mv643xx_eth_int_handler
|
||||
*
|
||||
@ -539,13 +590,19 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
|
||||
}
|
||||
/* PHY status changed */
|
||||
if (eth_int_cause_ext & (BIT16 | BIT20)) {
|
||||
struct ethtool_cmd cmd;
|
||||
|
||||
if (mii_link_ok(&mp->mii)) {
|
||||
mii_ethtool_gset(&mp->mii, &cmd);
|
||||
mv643xx_eth_update_pscr(dev, &cmd);
|
||||
if (!netif_carrier_ok(dev)) {
|
||||
netif_carrier_on(dev);
|
||||
netif_wake_queue(dev);
|
||||
/* Start TX queue */
|
||||
mv643xx_eth_port_enable_tx(port_num,
|
||||
mp->port_tx_queue_command);
|
||||
if (mp->tx_ring_size > mp->tx_desc_count +
|
||||
MAX_DESCS_PER_SKB) {
|
||||
netif_wake_queue(dev);
|
||||
/* Start TX queue */
|
||||
mv643xx_eth_port_enable_tx(port_num, mp->port_tx_queue_command);
|
||||
}
|
||||
}
|
||||
} else if (netif_carrier_ok(dev)) {
|
||||
netif_stop_queue(dev);
|
||||
@ -729,6 +786,34 @@ static void ether_init_tx_desc_ring(struct mv643xx_private *mp)
|
||||
mp->port_tx_queue_command = 1;
|
||||
}
|
||||
|
||||
static int mv643xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct mv643xx_private *mp = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
spin_lock_irq(&mp->lock);
|
||||
err = mii_ethtool_sset(&mp->mii, cmd);
|
||||
spin_unlock_irq(&mp->lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mv643xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct mv643xx_private *mp = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
spin_lock_irq(&mp->lock);
|
||||
err = mii_ethtool_gset(&mp->mii, cmd);
|
||||
spin_unlock_irq(&mp->lock);
|
||||
|
||||
/* The PHY may support 1000baseT_Half, but the mv643xx does not */
|
||||
cmd->supported &= ~SUPPORTED_1000baseT_Half;
|
||||
cmd->advertising &= ~ADVERTISED_1000baseT_Half;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* mv643xx_eth_open
|
||||
*
|
||||
@ -842,6 +927,10 @@ static int mv643xx_eth_open(struct net_device *dev)
|
||||
|
||||
mv643xx_eth_rx_task(dev); /* Fill RX ring with skb's */
|
||||
|
||||
/* Clear any pending ethernet port interrupts */
|
||||
mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
|
||||
mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
|
||||
|
||||
eth_port_start(dev);
|
||||
|
||||
/* Interrupt Coalescing */
|
||||
@ -854,16 +943,13 @@ static int mv643xx_eth_open(struct net_device *dev)
|
||||
mp->tx_int_coal =
|
||||
eth_port_set_tx_coal(port_num, 133000000, MV643XX_TX_COAL);
|
||||
|
||||
/* Clear any pending ethernet port interrupts */
|
||||
mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
|
||||
mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
|
||||
|
||||
/* Unmask phy and link status changes interrupts */
|
||||
mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
|
||||
INT_UNMASK_ALL_EXT);
|
||||
|
||||
/* Unmask RX buffer and TX end interrupt */
|
||||
mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL);
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_tx_skb:
|
||||
@ -1318,6 +1404,35 @@ static void mv643xx_netpoll(struct net_device *netdev)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void mv643xx_init_ethtool_cmd(struct net_device *dev, int phy_address,
|
||||
int speed, int duplex,
|
||||
struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct mv643xx_private *mp = netdev_priv(dev);
|
||||
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
|
||||
cmd->port = PORT_MII;
|
||||
cmd->transceiver = XCVR_INTERNAL;
|
||||
cmd->phy_address = phy_address;
|
||||
|
||||
if (speed == 0) {
|
||||
cmd->autoneg = AUTONEG_ENABLE;
|
||||
/* mii lib checks, but doesn't use speed on AUTONEG_ENABLE */
|
||||
cmd->speed = SPEED_100;
|
||||
cmd->advertising = ADVERTISED_10baseT_Half |
|
||||
ADVERTISED_10baseT_Full |
|
||||
ADVERTISED_100baseT_Half |
|
||||
ADVERTISED_100baseT_Full;
|
||||
if (mp->mii.supports_gmii)
|
||||
cmd->advertising |= ADVERTISED_1000baseT_Full;
|
||||
} else {
|
||||
cmd->autoneg = AUTONEG_DISABLE;
|
||||
cmd->speed = speed;
|
||||
cmd->duplex = duplex;
|
||||
}
|
||||
}
|
||||
|
||||
/*/
|
||||
* mv643xx_eth_probe
|
||||
*
|
||||
@ -1338,6 +1453,10 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
|
||||
u8 *p;
|
||||
struct resource *res;
|
||||
int err;
|
||||
struct ethtool_cmd cmd;
|
||||
u32 pscr;
|
||||
int duplex;
|
||||
int speed;
|
||||
|
||||
dev = alloc_etherdev(sizeof(struct mv643xx_private));
|
||||
if (!dev)
|
||||
@ -1375,6 +1494,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
|
||||
dev->tx_queue_len = mp->tx_ring_size;
|
||||
dev->base_addr = 0;
|
||||
dev->change_mtu = mv643xx_eth_change_mtu;
|
||||
dev->do_ioctl = mv643xx_eth_do_ioctl;
|
||||
SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops);
|
||||
|
||||
#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
|
||||
@ -1452,10 +1572,35 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
|
||||
pr_debug("MV643xx ethernet port %d: "
|
||||
"No PHY detected at addr %d\n",
|
||||
port_num, ethernet_phy_get(port_num));
|
||||
return err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
|
||||
pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE;
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
|
||||
pscr = mp->port_serial_control;
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
|
||||
|
||||
if (!(pscr & MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX) &&
|
||||
!(pscr & MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII))
|
||||
speed = 0;
|
||||
else if (pscr & MV643XX_ETH_PORT_STATUS_GMII_1000)
|
||||
speed = SPEED_1000;
|
||||
else if (pscr & MV643XX_ETH_PORT_STATUS_MII_100)
|
||||
speed = SPEED_100;
|
||||
else
|
||||
speed = SPEED_10;
|
||||
|
||||
if (pscr & MV643XX_ETH_PORT_STATUS_FULL_DUPLEX)
|
||||
duplex = DUPLEX_FULL;
|
||||
else
|
||||
duplex = DUPLEX_HALF;
|
||||
|
||||
ethernet_phy_reset(mp->port_num);
|
||||
mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii);
|
||||
mv643xx_init_ethtool_cmd(dev, mp->mii.phy_id, speed, duplex, &cmd);
|
||||
mv643xx_eth_update_pscr(dev, &cmd);
|
||||
mv643xx_set_settings(dev, &cmd);
|
||||
|
||||
err = register_netdev(dev);
|
||||
if (err)
|
||||
@ -1775,8 +1920,6 @@ static void eth_port_init(struct mv643xx_private *mp)
|
||||
eth_port_reset(mp->port_num);
|
||||
|
||||
eth_port_init_mac_tables(mp->port_num);
|
||||
|
||||
ethernet_phy_reset(mp->port_num);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1811,6 +1954,8 @@ static void eth_port_start(struct net_device *dev)
|
||||
struct mv643xx_private *mp = netdev_priv(dev);
|
||||
unsigned int port_num = mp->port_num;
|
||||
int tx_curr_desc, rx_curr_desc;
|
||||
u32 pscr;
|
||||
struct ethtool_cmd ethtool_cmd;
|
||||
|
||||
/* Assignment of Tx CTRP of given queue */
|
||||
tx_curr_desc = mp->tx_curr_desc_q;
|
||||
@ -1828,31 +1973,35 @@ static void eth_port_start(struct net_device *dev)
|
||||
/* Assign port configuration and command. */
|
||||
mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), mp->port_config);
|
||||
|
||||
mv_write(MV643XX_ETH_PORT_CONFIG_EXTEND_REG(port_num),
|
||||
mp->port_config_extend);
|
||||
pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
|
||||
pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE;
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
|
||||
|
||||
pscr &= ~MV643XX_ETH_FORCE_LINK_PASS;
|
||||
pscr |= MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
|
||||
MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII |
|
||||
MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX |
|
||||
MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL |
|
||||
MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED;
|
||||
|
||||
/* Increase the Rx side buffer size if supporting GigE */
|
||||
if (mp->port_serial_control & MV643XX_ETH_SET_GMII_SPEED_TO_1000)
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
|
||||
(mp->port_serial_control & 0xfff1ffff) | (0x5 << 17));
|
||||
else
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
|
||||
mp->port_serial_control);
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
|
||||
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
|
||||
mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)) |
|
||||
MV643XX_ETH_SERIAL_PORT_ENABLE);
|
||||
pscr |= MV643XX_ETH_SERIAL_PORT_ENABLE;
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
|
||||
|
||||
/* Assign port SDMA configuration */
|
||||
mv_write(MV643XX_ETH_SDMA_CONFIG_REG(port_num),
|
||||
mp->port_sdma_config);
|
||||
mv_write(MV643XX_ETH_SDMA_CONFIG_REG(port_num), mp->port_sdma_config);
|
||||
|
||||
/* Enable port Rx. */
|
||||
mv643xx_eth_port_enable_rx(port_num, mp->port_rx_queue_command);
|
||||
|
||||
/* Disable port bandwidth limits by clearing MTU register */
|
||||
mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0);
|
||||
|
||||
/* save phy settings across reset */
|
||||
mv643xx_get_settings(dev, ðtool_cmd);
|
||||
ethernet_phy_reset(mp->port_num);
|
||||
mv643xx_set_settings(dev, ðtool_cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2324,6 +2473,12 @@ static void ethernet_phy_reset(unsigned int eth_port_num)
|
||||
eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data);
|
||||
phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */
|
||||
eth_port_write_smi_reg(eth_port_num, 0, phy_reg_data);
|
||||
|
||||
/* wait for PHY to come out of reset */
|
||||
do {
|
||||
udelay(1);
|
||||
eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data);
|
||||
} while (phy_reg_data & 0x8000);
|
||||
}
|
||||
|
||||
static void mv643xx_eth_port_enable_tx(unsigned int port_num,
|
||||
@ -2417,20 +2572,13 @@ static void eth_port_reset(unsigned int port_num)
|
||||
|
||||
/* Reset the Enable bit in the Configuration Register */
|
||||
reg_data = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
|
||||
reg_data &= ~MV643XX_ETH_SERIAL_PORT_ENABLE;
|
||||
reg_data &= ~(MV643XX_ETH_SERIAL_PORT_ENABLE |
|
||||
MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL |
|
||||
MV643XX_ETH_FORCE_LINK_PASS);
|
||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data);
|
||||
}
|
||||
|
||||
|
||||
static int eth_port_autoneg_supported(unsigned int eth_port_num)
|
||||
{
|
||||
unsigned int phy_reg_data0;
|
||||
|
||||
eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data0);
|
||||
|
||||
return phy_reg_data0 & 0x1000;
|
||||
}
|
||||
|
||||
/*
|
||||
* eth_port_read_smi_reg - Read PHY registers
|
||||
*
|
||||
@ -2989,111 +3137,6 @@ static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
|
||||
#define MV643XX_STATS_LEN \
|
||||
sizeof(mv643xx_gstrings_stats) / sizeof(struct mv643xx_stats)
|
||||
|
||||
static int
|
||||
mv643xx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
||||
{
|
||||
struct mv643xx_private *mp = netdev->priv;
|
||||
int port_num = mp->port_num;
|
||||
int autoneg = eth_port_autoneg_supported(port_num);
|
||||
int mode_10_bit;
|
||||
int auto_duplex;
|
||||
int half_duplex = 0;
|
||||
int full_duplex = 0;
|
||||
int auto_speed;
|
||||
int speed_10 = 0;
|
||||
int speed_100 = 0;
|
||||
int speed_1000 = 0;
|
||||
|
||||
u32 pcs = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
|
||||
u32 psr = mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num));
|
||||
|
||||
mode_10_bit = psr & MV643XX_ETH_PORT_STATUS_MODE_10_BIT;
|
||||
|
||||
if (mode_10_bit) {
|
||||
ecmd->supported = SUPPORTED_10baseT_Half;
|
||||
} else {
|
||||
ecmd->supported = (SUPPORTED_10baseT_Half |
|
||||
SUPPORTED_10baseT_Full |
|
||||
SUPPORTED_100baseT_Half |
|
||||
SUPPORTED_100baseT_Full |
|
||||
SUPPORTED_1000baseT_Full |
|
||||
(autoneg ? SUPPORTED_Autoneg : 0) |
|
||||
SUPPORTED_TP);
|
||||
|
||||
auto_duplex = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX);
|
||||
auto_speed = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII);
|
||||
|
||||
ecmd->advertising = ADVERTISED_TP;
|
||||
|
||||
if (autoneg) {
|
||||
ecmd->advertising |= ADVERTISED_Autoneg;
|
||||
|
||||
if (auto_duplex) {
|
||||
half_duplex = 1;
|
||||
full_duplex = 1;
|
||||
} else {
|
||||
if (pcs & MV643XX_ETH_SET_FULL_DUPLEX_MODE)
|
||||
full_duplex = 1;
|
||||
else
|
||||
half_duplex = 1;
|
||||
}
|
||||
|
||||
if (auto_speed) {
|
||||
speed_10 = 1;
|
||||
speed_100 = 1;
|
||||
speed_1000 = 1;
|
||||
} else {
|
||||
if (pcs & MV643XX_ETH_SET_GMII_SPEED_TO_1000)
|
||||
speed_1000 = 1;
|
||||
else if (pcs & MV643XX_ETH_SET_MII_SPEED_TO_100)
|
||||
speed_100 = 1;
|
||||
else
|
||||
speed_10 = 1;
|
||||
}
|
||||
|
||||
if (speed_10 & half_duplex)
|
||||
ecmd->advertising |= ADVERTISED_10baseT_Half;
|
||||
if (speed_10 & full_duplex)
|
||||
ecmd->advertising |= ADVERTISED_10baseT_Full;
|
||||
if (speed_100 & half_duplex)
|
||||
ecmd->advertising |= ADVERTISED_100baseT_Half;
|
||||
if (speed_100 & full_duplex)
|
||||
ecmd->advertising |= ADVERTISED_100baseT_Full;
|
||||
if (speed_1000)
|
||||
ecmd->advertising |= ADVERTISED_1000baseT_Full;
|
||||
}
|
||||
}
|
||||
|
||||
ecmd->port = PORT_TP;
|
||||
ecmd->phy_address = ethernet_phy_get(port_num);
|
||||
|
||||
ecmd->transceiver = XCVR_EXTERNAL;
|
||||
|
||||
if (netif_carrier_ok(netdev)) {
|
||||
if (mode_10_bit)
|
||||
ecmd->speed = SPEED_10;
|
||||
else {
|
||||
if (psr & MV643XX_ETH_PORT_STATUS_GMII_1000)
|
||||
ecmd->speed = SPEED_1000;
|
||||
else if (psr & MV643XX_ETH_PORT_STATUS_MII_100)
|
||||
ecmd->speed = SPEED_100;
|
||||
else
|
||||
ecmd->speed = SPEED_10;
|
||||
}
|
||||
|
||||
if (psr & MV643XX_ETH_PORT_STATUS_FULL_DUPLEX)
|
||||
ecmd->duplex = DUPLEX_FULL;
|
||||
else
|
||||
ecmd->duplex = DUPLEX_HALF;
|
||||
} else {
|
||||
ecmd->speed = -1;
|
||||
ecmd->duplex = -1;
|
||||
}
|
||||
|
||||
ecmd->autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mv643xx_get_drvinfo(struct net_device *netdev,
|
||||
struct ethtool_drvinfo *drvinfo)
|
||||
{
|
||||
@ -3140,15 +3183,41 @@ static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset,
|
||||
}
|
||||
}
|
||||
|
||||
static u32 mv643xx_eth_get_link(struct net_device *dev)
|
||||
{
|
||||
struct mv643xx_private *mp = netdev_priv(dev);
|
||||
|
||||
return mii_link_ok(&mp->mii);
|
||||
}
|
||||
|
||||
static int mv643xx_eth_nway_restart(struct net_device *dev)
|
||||
{
|
||||
struct mv643xx_private *mp = netdev_priv(dev);
|
||||
|
||||
return mii_nway_restart(&mp->mii);
|
||||
}
|
||||
|
||||
static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
struct mv643xx_private *mp = netdev_priv(dev);
|
||||
|
||||
return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL);
|
||||
}
|
||||
|
||||
static struct ethtool_ops mv643xx_ethtool_ops = {
|
||||
.get_settings = mv643xx_get_settings,
|
||||
.set_settings = mv643xx_set_settings,
|
||||
.get_drvinfo = mv643xx_get_drvinfo,
|
||||
.get_link = ethtool_op_get_link,
|
||||
.get_link = mv643xx_eth_get_link,
|
||||
.get_sg = ethtool_op_get_sg,
|
||||
.set_sg = ethtool_op_set_sg,
|
||||
.get_strings = mv643xx_get_strings,
|
||||
.get_stats_count = mv643xx_get_stats_count,
|
||||
.get_ethtool_stats = mv643xx_get_ethtool_stats,
|
||||
.get_strings = mv643xx_get_strings,
|
||||
.get_stats_count = mv643xx_get_stats_count,
|
||||
.get_ethtool_stats = mv643xx_get_ethtool_stats,
|
||||
.nway_reset = mv643xx_eth_nway_restart,
|
||||
};
|
||||
|
||||
/************* End ethtool support *************************/
|
||||
|
@ -1214,6 +1214,7 @@ struct mv64xxx_i2c_pdata {
|
||||
#define MV643XX_ETH_FORCE_BP_MODE_NO_JAM 0
|
||||
#define MV643XX_ETH_FORCE_BP_MODE_JAM_TX (1<<7)
|
||||
#define MV643XX_ETH_FORCE_BP_MODE_JAM_TX_ON_RX_ERR (1<<8)
|
||||
#define MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED (1<<9)
|
||||
#define MV643XX_ETH_FORCE_LINK_FAIL 0
|
||||
#define MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL (1<<10)
|
||||
#define MV643XX_ETH_RETRANSMIT_16_ATTEMPTS 0
|
||||
@ -1243,6 +1244,8 @@ struct mv64xxx_i2c_pdata {
|
||||
#define MV643XX_ETH_SET_MII_SPEED_TO_10 0
|
||||
#define MV643XX_ETH_SET_MII_SPEED_TO_100 (1<<24)
|
||||
|
||||
#define MV643XX_ETH_MAX_RX_PACKET_MASK (0x7<<17)
|
||||
|
||||
#define MV643XX_ETH_PORT_SERIAL_CONTROL_DEFAULT_VALUE \
|
||||
MV643XX_ETH_DO_NOT_FORCE_LINK_PASS | \
|
||||
MV643XX_ETH_ENABLE_AUTO_NEG_FOR_DUPLX | \
|
||||
|
Loading…
Reference in New Issue
Block a user