diff options
Diffstat (limited to 'drivers/net/ethernet/realtek')
-rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 5eb6858ed0a7..0517a6a252f1 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1626,21 +1626,32 @@ static void __rtl8169_set_features(struct net_device *dev, netdev_features_t features) { struct rtl8169_private *tp = netdev_priv(dev); - + netdev_features_t changed = features ^ dev->features; void __iomem *ioaddr = tp->mmio_addr; - if (features & NETIF_F_RXCSUM) - tp->cp_cmd |= RxChkSum; - else - tp->cp_cmd &= ~RxChkSum; + if (!(changed & (NETIF_F_RXALL | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX))) + return; - if (dev->features & NETIF_F_HW_VLAN_RX) - tp->cp_cmd |= RxVlan; - else - tp->cp_cmd &= ~RxVlan; + if (changed & (NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX)) { + if (features & NETIF_F_RXCSUM) + tp->cp_cmd |= RxChkSum; + else + tp->cp_cmd &= ~RxChkSum; - RTL_W16(CPlusCmd, tp->cp_cmd); - RTL_R16(CPlusCmd); + if (dev->features & NETIF_F_HW_VLAN_RX) + tp->cp_cmd |= RxVlan; + else + tp->cp_cmd &= ~RxVlan; + + RTL_W16(CPlusCmd, tp->cp_cmd); + RTL_R16(CPlusCmd); + } + if (changed & NETIF_F_RXALL) { + int tmp = (RTL_R32(RxConfig) & ~(AcceptErr | AcceptRunt)); + if (features & NETIF_F_RXALL) + tmp |= (AcceptErr | AcceptRunt); + RTL_W32(RxConfig, tmp); + } } static int rtl8169_set_features(struct net_device *dev, @@ -4174,6 +4185,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* 8110SCd requires hardware Rx VLAN - disallow toggling */ dev->hw_features &= ~NETIF_F_HW_VLAN_RX; + dev->hw_features |= NETIF_F_RXALL; + tp->hw_start = cfg->hw_start; tp->event_slow = cfg->event_slow; @@ -5747,11 +5760,20 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); dev->stats.rx_fifo_errors++; } + if ((status & (RxRUNT | RxCRC)) && + !(status & (RxRWT | RxFOVF)) && + (dev->features & NETIF_F_RXALL)) + goto process_pkt; + rtl8169_mark_to_asic(desc, rx_buf_sz); } else { struct sk_buff *skb; - dma_addr_t addr = le64_to_cpu(desc->addr); - int pkt_size = (status & 0x00003fff) - 4; + dma_addr_t addr; + int pkt_size; + +process_pkt: + addr = le64_to_cpu(desc->addr); + pkt_size = (status & 0x00003fff) - 4; /* * The driver does not support incoming fragmented @@ -6025,6 +6047,9 @@ static void rtl_set_rx_mode(struct net_device *dev) } } + if (dev->features & NETIF_F_RXALL) + rx_mode |= (AcceptErr | AcceptRunt); + tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode; if (tp->mac_version > RTL_GIGA_MAC_VER_06) { |