Commit d344c4f3 authored by RongQing.Li's avatar RongQing.Li Committed by David S. Miller

pch_gbe: reprogram multicast address register on reset

The reset logic after a Rx FIFO overrun will clear the programmed
multicast addresses. This patch fixes the issue by reprogramming the
registers after the reset.

The commit eefc48b0 ("pch_gbe: reprogram multicast address register on
reset") tried to fix this problem, but it introduces unnecessary
codes. In fact, all multicast addresses have been saved in netdev->mc,
So we can call pch_gbe_set_multi() directly after reset_hw and
reset_rx.

This commit kills 50+ line codes

Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Takahiro Shimizu <tshimizu818@gmail.com>
Signed-off-by: default avatarRongQing.Li <roy.qing.li@gmail.com>
Acked-by: default avatarRichard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1d0c0b32
...@@ -120,6 +120,7 @@ static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; ...@@ -120,6 +120,7 @@ static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT;
static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg);
static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg,
int data); int data);
static void pch_gbe_set_multi(struct net_device *netdev);
#ifdef CONFIG_PCH_PTP #ifdef CONFIG_PCH_PTP
static struct sock_filter ptp_filter[] = { static struct sock_filter ptp_filter[] = {
...@@ -390,59 +391,14 @@ static void pch_gbe_mac_mar_set(struct pch_gbe_hw *hw, u8 * addr, u32 index) ...@@ -390,59 +391,14 @@ static void pch_gbe_mac_mar_set(struct pch_gbe_hw *hw, u8 * addr, u32 index)
pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY); pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);
} }
/**
* pch_gbe_mac_save_mac_addr_regs - Save MAC addresse registers
* @hw: Pointer to the HW structure
* @addr: Pointer to the MAC address
* @index: MAC address array register
*/
static void
pch_gbe_mac_save_mac_addr_regs(struct pch_gbe_hw *hw,
struct pch_gbe_regs_mac_adr *mac_adr, u32 index)
{
mac_adr->high = ioread32(&hw->reg->mac_adr[index].high);
mac_adr->low = ioread32(&hw->reg->mac_adr[index].low);
}
/**
* pch_gbe_mac_store_mac_addr_regs - Store MAC addresse registers
* @hw: Pointer to the HW structure
* @addr: Pointer to the MAC address
* @index: MAC address array register
*/
static void
pch_gbe_mac_store_mac_addr_regs(struct pch_gbe_hw *hw,
struct pch_gbe_regs_mac_adr *mac_adr, u32 index)
{
u32 adrmask;
adrmask = ioread32(&hw->reg->ADDR_MASK);
iowrite32((adrmask | (0x0001 << index)), &hw->reg->ADDR_MASK);
/* wait busy */
pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);
/* Set the MAC address to the MAC address xA/xB register */
iowrite32(mac_adr->high, &hw->reg->mac_adr[index].high);
iowrite32(mac_adr->low, &hw->reg->mac_adr[index].low);
iowrite32((adrmask & ~(0x0001 << index)), &hw->reg->ADDR_MASK);
/* wait busy */
pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);
}
#define MAC_ADDR_LIST_NUM 16
/** /**
* pch_gbe_mac_reset_hw - Reset hardware * pch_gbe_mac_reset_hw - Reset hardware
* @hw: Pointer to the HW structure * @hw: Pointer to the HW structure
*/ */
static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw)
{ {
struct pch_gbe_regs_mac_adr mac_addr_list[MAC_ADDR_LIST_NUM];
int i;
/* Read the MAC address. and store to the private data */ /* Read the MAC address. and store to the private data */
pch_gbe_mac_read_mac_addr(hw); pch_gbe_mac_read_mac_addr(hw);
/* Read other MAC addresses */
for (i = 1; i < MAC_ADDR_LIST_NUM; i++)
pch_gbe_mac_save_mac_addr_regs(hw, &mac_addr_list[i], i);
iowrite32(PCH_GBE_ALL_RST, &hw->reg->RESET); iowrite32(PCH_GBE_ALL_RST, &hw->reg->RESET);
#ifdef PCH_GBE_MAC_IFOP_RGMII #ifdef PCH_GBE_MAC_IFOP_RGMII
iowrite32(PCH_GBE_MODE_GMII_ETHER, &hw->reg->MODE); iowrite32(PCH_GBE_MODE_GMII_ETHER, &hw->reg->MODE);
...@@ -450,26 +406,17 @@ static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) ...@@ -450,26 +406,17 @@ static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw)
pch_gbe_wait_clr_bit(&hw->reg->RESET, PCH_GBE_ALL_RST); pch_gbe_wait_clr_bit(&hw->reg->RESET, PCH_GBE_ALL_RST);
/* Setup the receive addresses */ /* Setup the receive addresses */
pch_gbe_mac_mar_set(hw, hw->mac.addr, 0); pch_gbe_mac_mar_set(hw, hw->mac.addr, 0);
for (i = 1; i < MAC_ADDR_LIST_NUM; i++)
pch_gbe_mac_store_mac_addr_regs(hw, &mac_addr_list[i], i);
return; return;
} }
static void pch_gbe_mac_reset_rx(struct pch_gbe_hw *hw) static void pch_gbe_mac_reset_rx(struct pch_gbe_hw *hw)
{ {
struct pch_gbe_regs_mac_adr mac_addr_list[MAC_ADDR_LIST_NUM];
int i;
/* Read the MAC addresses. and store to the private data */ /* Read the MAC addresses. and store to the private data */
pch_gbe_mac_read_mac_addr(hw); pch_gbe_mac_read_mac_addr(hw);
for (i = 1; i < MAC_ADDR_LIST_NUM; i++)
pch_gbe_mac_save_mac_addr_regs(hw, &mac_addr_list[i], i);
iowrite32(PCH_GBE_RX_RST, &hw->reg->RESET); iowrite32(PCH_GBE_RX_RST, &hw->reg->RESET);
pch_gbe_wait_clr_bit_irq(&hw->reg->RESET, PCH_GBE_RX_RST); pch_gbe_wait_clr_bit_irq(&hw->reg->RESET, PCH_GBE_RX_RST);
/* Setup the MAC addresses */ /* Setup the MAC addresses */
pch_gbe_mac_mar_set(hw, hw->mac.addr, 0); pch_gbe_mac_mar_set(hw, hw->mac.addr, 0);
for (i = 1; i < MAC_ADDR_LIST_NUM; i++)
pch_gbe_mac_store_mac_addr_regs(hw, &mac_addr_list[i], i);
return; return;
} }
...@@ -836,6 +783,8 @@ void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter) ...@@ -836,6 +783,8 @@ void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter)
void pch_gbe_reset(struct pch_gbe_adapter *adapter) void pch_gbe_reset(struct pch_gbe_adapter *adapter)
{ {
pch_gbe_mac_reset_hw(&adapter->hw); pch_gbe_mac_reset_hw(&adapter->hw);
/* reprogram multicast address register after reset */
pch_gbe_set_multi(adapter->netdev);
/* Setup the receive address. */ /* Setup the receive address. */
pch_gbe_mac_init_rx_addrs(&adapter->hw, PCH_GBE_MAR_ENTRIES); pch_gbe_mac_init_rx_addrs(&adapter->hw, PCH_GBE_MAR_ENTRIES);
if (pch_gbe_hal_init_hw(&adapter->hw)) if (pch_gbe_hal_init_hw(&adapter->hw))
...@@ -1398,6 +1347,8 @@ static void pch_gbe_stop_receive(struct pch_gbe_adapter *adapter) ...@@ -1398,6 +1347,8 @@ static void pch_gbe_stop_receive(struct pch_gbe_adapter *adapter)
/* Stop Receive */ /* Stop Receive */
pch_gbe_mac_reset_rx(hw); pch_gbe_mac_reset_rx(hw);
} }
/* reprogram multicast address register after reset */
pch_gbe_set_multi(adapter->netdev);
} }
static void pch_gbe_start_receive(struct pch_gbe_hw *hw) static void pch_gbe_start_receive(struct pch_gbe_hw *hw)
...@@ -1980,7 +1931,6 @@ static int pch_gbe_request_irq(struct pch_gbe_adapter *adapter) ...@@ -1980,7 +1931,6 @@ static int pch_gbe_request_irq(struct pch_gbe_adapter *adapter)
} }
static void pch_gbe_set_multi(struct net_device *netdev);
/** /**
* pch_gbe_up - Up GbE network device * pch_gbe_up - Up GbE network device
* @adapter: Board private structure * @adapter: Board private structure
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment