diff options
Diffstat (limited to 'drivers/net/ethernet/marvell')
| -rw-r--r-- | drivers/net/ethernet/marvell/mv643xx_eth.c | 55 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/sky2.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/sky2.h | 2 | 
3 files changed, 53 insertions, 6 deletions
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 29140502b71..6562c736a1d 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -1081,6 +1081,45 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq)  /* mii management interface *************************************************/ +static void mv643xx_adjust_pscr(struct mv643xx_eth_private *mp) +{ +	u32 pscr = rdlp(mp, PORT_SERIAL_CONTROL); +	u32 autoneg_disable = FORCE_LINK_PASS | +	             DISABLE_AUTO_NEG_SPEED_GMII | +		     DISABLE_AUTO_NEG_FOR_FLOW_CTRL | +		     DISABLE_AUTO_NEG_FOR_DUPLEX; + +	if (mp->phy->autoneg == AUTONEG_ENABLE) { +		/* enable auto negotiation */ +		pscr &= ~autoneg_disable; +		goto out_write; +	} + +	pscr |= autoneg_disable; + +	if (mp->phy->speed == SPEED_1000) { +		/* force gigabit, half duplex not supported */ +		pscr |= SET_GMII_SPEED_TO_1000; +		pscr |= SET_FULL_DUPLEX_MODE; +		goto out_write; +	} + +	pscr &= ~SET_GMII_SPEED_TO_1000; + +	if (mp->phy->speed == SPEED_100) +		pscr |= SET_MII_SPEED_TO_100; +	else +		pscr &= ~SET_MII_SPEED_TO_100; + +	if (mp->phy->duplex == DUPLEX_FULL) +		pscr |= SET_FULL_DUPLEX_MODE; +	else +		pscr &= ~SET_FULL_DUPLEX_MODE; + +out_write: +	wrlp(mp, PORT_SERIAL_CONTROL, pscr); +} +  static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)  {  	struct mv643xx_eth_shared_private *msp = dev_id; @@ -1499,6 +1538,7 @@ static int  mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)  {  	struct mv643xx_eth_private *mp = netdev_priv(dev); +	int ret;  	if (mp->phy == NULL)  		return -EINVAL; @@ -1508,7 +1548,10 @@ mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)  	 */  	cmd->advertising &= ~ADVERTISED_1000baseT_Half; -	return phy_ethtool_sset(mp->phy, cmd); +	ret = phy_ethtool_sset(mp->phy, cmd); +	if (!ret) +		mv643xx_adjust_pscr(mp); +	return ret;  }  static void mv643xx_eth_get_drvinfo(struct net_device *dev, @@ -2442,11 +2485,15 @@ static int mv643xx_eth_stop(struct net_device *dev)  static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)  {  	struct mv643xx_eth_private *mp = netdev_priv(dev); +	int ret; -	if (mp->phy != NULL) -		return phy_mii_ioctl(mp->phy, ifr, cmd); +	if (mp->phy == NULL) +		return -ENOTSUPP; -	return -EOPNOTSUPP; +	ret = phy_mii_ioctl(mp->phy, ifr, cmd); +	if (!ret) +		mv643xx_adjust_pscr(mp); +	return ret;  }  static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index fc07ca35721..6a0e671fcec 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -1067,7 +1067,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space)  		sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);  		sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2); -		tp = space - 2048/8; +		tp = space - 8192/8;  		sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);  		sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);  	} else { diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h index 615ac63ea86..ec6dcd80152 100644 --- a/drivers/net/ethernet/marvell/sky2.h +++ b/drivers/net/ethernet/marvell/sky2.h @@ -2074,7 +2074,7 @@ enum {  	GM_IS_RX_FF_OR	= 1<<1,	/* Receive FIFO Overrun */  	GM_IS_RX_COMPL	= 1<<0,	/* Frame Reception Complete */ -#define GMAC_DEF_MSK     GM_IS_TX_FF_UR +#define GMAC_DEF_MSK     (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR)  };  /*	GMAC_LINK_CTRL	16 bit	GMAC Link Control Reg (YUKON only) */  |