aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/skge.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r--drivers/net/skge.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 189203c95330..572f121b1f4e 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -1644,6 +1644,22 @@ static void yukon_reset(struct skge_hw *hw, int port)
1644 | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); 1644 | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
1645} 1645}
1646 1646
1647/* Apparently, early versions of Yukon-Lite had wrong chip_id? */
1648static int is_yukon_lite_a0(struct skge_hw *hw)
1649{
1650 u32 reg;
1651 int ret;
1652
1653 if (hw->chip_id != CHIP_ID_YUKON)
1654 return 0;
1655
1656 reg = skge_read32(hw, B2_FAR);
1657 skge_write8(hw, B2_FAR + 3, 0xff);
1658 ret = (skge_read8(hw, B2_FAR + 3) != 0);
1659 skge_write32(hw, B2_FAR, reg);
1660 return ret;
1661}
1662
1647static void yukon_mac_init(struct skge_hw *hw, int port) 1663static void yukon_mac_init(struct skge_hw *hw, int port)
1648{ 1664{
1649 struct skge_port *skge = netdev_priv(hw->dev[port]); 1665 struct skge_port *skge = netdev_priv(hw->dev[port]);
@@ -1759,9 +1775,11 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
1759 /* Configure Rx MAC FIFO */ 1775 /* Configure Rx MAC FIFO */
1760 skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); 1776 skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK);
1761 reg = GMF_OPER_ON | GMF_RX_F_FL_ON; 1777 reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
1762 if (hw->chip_id == CHIP_ID_YUKON_LITE && 1778
1763 hw->chip_rev >= CHIP_REV_YU_LITE_A3) 1779 /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
1780 if (is_yukon_lite_a0(hw))
1764 reg &= ~GMF_RX_F_FL_ON; 1781 reg &= ~GMF_RX_F_FL_ON;
1782
1765 skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); 1783 skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
1766 skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); 1784 skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
1767 /* 1785 /*
@@ -2820,21 +2838,29 @@ static void skge_netpoll(struct net_device *dev)
2820static int skge_set_mac_address(struct net_device *dev, void *p) 2838static int skge_set_mac_address(struct net_device *dev, void *p)
2821{ 2839{
2822 struct skge_port *skge = netdev_priv(dev); 2840 struct skge_port *skge = netdev_priv(dev);
2823 struct sockaddr *addr = p; 2841 struct skge_hw *hw = skge->hw;
2824 int err = 0; 2842 unsigned port = skge->port;
2843 const struct sockaddr *addr = p;
2825 2844
2826 if (!is_valid_ether_addr(addr->sa_data)) 2845 if (!is_valid_ether_addr(addr->sa_data))
2827 return -EADDRNOTAVAIL; 2846 return -EADDRNOTAVAIL;
2828 2847
2829 skge_down(dev); 2848 spin_lock_bh(&hw->phy_lock);
2830 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); 2849 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
2831 memcpy_toio(skge->hw->regs + B2_MAC_1 + skge->port*8, 2850 memcpy_toio(hw->regs + B2_MAC_1 + port*8,
2832 dev->dev_addr, ETH_ALEN); 2851 dev->dev_addr, ETH_ALEN);
2833 memcpy_toio(skge->hw->regs + B2_MAC_2 + skge->port*8, 2852 memcpy_toio(hw->regs + B2_MAC_2 + port*8,
2834 dev->dev_addr, ETH_ALEN); 2853 dev->dev_addr, ETH_ALEN);
2835 if (dev->flags & IFF_UP) 2854
2836 err = skge_up(dev); 2855 if (hw->chip_id == CHIP_ID_GENESIS)
2837 return err; 2856 xm_outaddr(hw, port, XM_SA, dev->dev_addr);
2857 else {
2858 gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
2859 gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
2860 }
2861 spin_unlock_bh(&hw->phy_lock);
2862
2863 return 0;
2838} 2864}
2839 2865
2840static const struct { 2866static const struct {