aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/realtek/r8169.c
diff options
context:
space:
mode:
authorBen Greear <greearb@candelatech.com>2012-02-10 10:04:33 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-02-24 04:56:27 -0500
commit6bbe021d405fff46b64a08dca51b06897b897a67 (patch)
treeda4693452e8ce75b456955914966a1f7c4739bd2 /drivers/net/ethernet/realtek/r8169.c
parenteeb69aa443e8cdc945405c48f21ce03f5a3b1f86 (diff)
r8169: Support RX-ALL flag.
This allows the NIC to receive packets with bad FCS and Runts, which can help when sniffing. NOTE: r8169, at least on my NIC, silently drops packets with bad FCS instead of counting them. It seems they are only received in any fashion if the RxCRC flag is set (which this patch allows). Signed-off-by: Ben Greear <greearb@candelatech.com>
Diffstat (limited to 'drivers/net/ethernet/realtek/r8169.c')
-rw-r--r--drivers/net/ethernet/realtek/r8169.c51
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,
1626 netdev_features_t features) 1626 netdev_features_t features)
1627{ 1627{
1628 struct rtl8169_private *tp = netdev_priv(dev); 1628 struct rtl8169_private *tp = netdev_priv(dev);
1629 1629 netdev_features_t changed = features ^ dev->features;
1630 void __iomem *ioaddr = tp->mmio_addr; 1630 void __iomem *ioaddr = tp->mmio_addr;
1631 1631
1632 if (features & NETIF_F_RXCSUM) 1632 if (!(changed & (NETIF_F_RXALL | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX)))
1633 tp->cp_cmd |= RxChkSum; 1633 return;
1634 else
1635 tp->cp_cmd &= ~RxChkSum;
1636 1634
1637 if (dev->features & NETIF_F_HW_VLAN_RX) 1635 if (changed & (NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX)) {
1638 tp->cp_cmd |= RxVlan; 1636 if (features & NETIF_F_RXCSUM)
1639 else 1637 tp->cp_cmd |= RxChkSum;
1640 tp->cp_cmd &= ~RxVlan; 1638 else
1639 tp->cp_cmd &= ~RxChkSum;
1641 1640
1642 RTL_W16(CPlusCmd, tp->cp_cmd); 1641 if (dev->features & NETIF_F_HW_VLAN_RX)
1643 RTL_R16(CPlusCmd); 1642 tp->cp_cmd |= RxVlan;
1643 else
1644 tp->cp_cmd &= ~RxVlan;
1645
1646 RTL_W16(CPlusCmd, tp->cp_cmd);
1647 RTL_R16(CPlusCmd);
1648 }
1649 if (changed & NETIF_F_RXALL) {
1650 int tmp = (RTL_R32(RxConfig) & ~(AcceptErr | AcceptRunt));
1651 if (features & NETIF_F_RXALL)
1652 tmp |= (AcceptErr | AcceptRunt);
1653 RTL_W32(RxConfig, tmp);
1654 }
1644} 1655}
1645 1656
1646static int rtl8169_set_features(struct net_device *dev, 1657static 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)
4174 /* 8110SCd requires hardware Rx VLAN - disallow toggling */ 4185 /* 8110SCd requires hardware Rx VLAN - disallow toggling */
4175 dev->hw_features &= ~NETIF_F_HW_VLAN_RX; 4186 dev->hw_features &= ~NETIF_F_HW_VLAN_RX;
4176 4187
4188 dev->hw_features |= NETIF_F_RXALL;
4189
4177 tp->hw_start = cfg->hw_start; 4190 tp->hw_start = cfg->hw_start;
4178 tp->event_slow = cfg->event_slow; 4191 tp->event_slow = cfg->event_slow;
4179 4192
@@ -5747,11 +5760,20 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget
5747 rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); 5760 rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
5748 dev->stats.rx_fifo_errors++; 5761 dev->stats.rx_fifo_errors++;
5749 } 5762 }
5763 if ((status & (RxRUNT | RxCRC)) &&
5764 !(status & (RxRWT | RxFOVF)) &&
5765 (dev->features & NETIF_F_RXALL))
5766 goto process_pkt;
5767
5750 rtl8169_mark_to_asic(desc, rx_buf_sz); 5768 rtl8169_mark_to_asic(desc, rx_buf_sz);
5751 } else { 5769 } else {
5752 struct sk_buff *skb; 5770 struct sk_buff *skb;
5753 dma_addr_t addr = le64_to_cpu(desc->addr); 5771 dma_addr_t addr;
5754 int pkt_size = (status & 0x00003fff) - 4; 5772 int pkt_size;
5773
5774process_pkt:
5775 addr = le64_to_cpu(desc->addr);
5776 pkt_size = (status & 0x00003fff) - 4;
5755 5777
5756 /* 5778 /*
5757 * The driver does not support incoming fragmented 5779 * The driver does not support incoming fragmented
@@ -6025,6 +6047,9 @@ static void rtl_set_rx_mode(struct net_device *dev)
6025 } 6047 }
6026 } 6048 }
6027 6049
6050 if (dev->features & NETIF_F_RXALL)
6051 rx_mode |= (AcceptErr | AcceptRunt);
6052
6028 tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode; 6053 tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode;
6029 6054
6030 if (tp->mac_version > RTL_GIGA_MAC_VER_06) { 6055 if (tp->mac_version > RTL_GIGA_MAC_VER_06) {