mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 23:58:05 +00:00
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. [ RC - Rebased Takahiro's changes and wrote a commit message explaining the changes. ] Signed-off-by: Takahiro Shimizu <tshimizu818@gmail.com> Signed-off-by: Richard Cochran <richardcochran@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5481c8cd83
commit
eefc48b078
1 changed files with 57 additions and 3 deletions
|
@ -382,32 +382,86 @@ 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);
|
||||||
#endif
|
#endif
|
||||||
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 address */
|
/* 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)
|
||||||
{
|
{
|
||||||
/* Read the MAC address. and store to the private data */
|
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 */
|
||||||
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 address */
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue