diff options
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r-- | drivers/net/skge.c | 46 |
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? */ | ||
1648 | static 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 | |||
1647 | static void yukon_mac_init(struct skge_hw *hw, int port) | 1663 | static 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) | |||
2820 | static int skge_set_mac_address(struct net_device *dev, void *p) | 2838 | static 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 | ||
2840 | static const struct { | 2866 | static const struct { |