Commit 81cd17a4 authored by Heiner Kallweit's avatar Heiner Kallweit Committed by David S. Miller
Browse files

r8169: improve rtl_set_rx_mode



This patch improves and simplifies rtl_set_rx_mode a little.
No functional change intended.

Signed-off-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ce599b1a
Loading
Loading
Loading
Loading
+22 −30
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@

/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
   The RTL chips use a 64 element hash table based on the Ethernet CRC. */
static const int multicast_filter_limit = 32;
#define	MC_FILTER_LIMIT	32

#define TX_DMA_BURST	7	/* Maximum PCI burst, '7' is unlimited */
#define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */
@@ -4146,54 +4146,46 @@ static void rtl8169_set_magic_reg(struct rtl8169_private *tp, unsigned mac_versi

static void rtl_set_rx_mode(struct net_device *dev)
{
	u32 rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
	/* Multicast hash filter */
	u32 mc_filter[2] = { 0xffffffff, 0xffffffff };
	struct rtl8169_private *tp = netdev_priv(dev);
	u32 mc_filter[2];	/* Multicast hash filter */
	int rx_mode;
	u32 tmp = 0;
	u32 tmp;

	if (dev->flags & IFF_PROMISC) {
		/* Unconditionally log net taps. */
		netif_notice(tp, link, dev, "Promiscuous mode enabled\n");
		rx_mode =
		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
		    AcceptAllPhys;
		mc_filter[1] = mc_filter[0] = 0xffffffff;
	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
		   (dev->flags & IFF_ALLMULTI)) {
		/* Too many to filter perfectly -- accept all multicasts. */
		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
		mc_filter[1] = mc_filter[0] = 0xffffffff;
		rx_mode |= AcceptAllPhys;
	} else if (netdev_mc_count(dev) > MC_FILTER_LIMIT ||
		   dev->flags & IFF_ALLMULTI ||
		   tp->mac_version == RTL_GIGA_MAC_VER_35) {
		/* accept all multicasts */
	} else if (netdev_mc_empty(dev)) {
		rx_mode &= ~AcceptMulticast;
	} else {
		struct netdev_hw_addr *ha;

		rx_mode = AcceptBroadcast | AcceptMyPhys;
		mc_filter[1] = mc_filter[0] = 0;
		netdev_for_each_mc_addr(ha, dev) {
			int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
			rx_mode |= AcceptMulticast;
			u32 bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
			mc_filter[bit_nr >> 5] |= BIT(bit_nr & 31);
		}
	}

	if (dev->features & NETIF_F_RXALL)
		rx_mode |= (AcceptErr | AcceptRunt);

	tmp = (RTL_R32(tp, RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode;

		if (tp->mac_version > RTL_GIGA_MAC_VER_06) {
		u32 data = mc_filter[0];

			tmp = mc_filter[0];
			mc_filter[0] = swab32(mc_filter[1]);
		mc_filter[1] = swab32(data);
			mc_filter[1] = swab32(tmp);
		}
	}

	if (tp->mac_version == RTL_GIGA_MAC_VER_35)
		mc_filter[1] = mc_filter[0] = 0xffffffff;
	if (dev->features & NETIF_F_RXALL)
		rx_mode |= (AcceptErr | AcceptRunt);

	RTL_W32(tp, MAR0 + 4, mc_filter[1]);
	RTL_W32(tp, MAR0 + 0, mc_filter[0]);

	RTL_W32(tp, RxConfig, tmp);
	tmp = RTL_R32(tp, RxConfig);
	RTL_W32(tp, RxConfig, (tmp & ~RX_CONFIG_ACCEPT_MASK) | rx_mode);
}

DECLARE_RTL_COND(rtl_csiar_cond)