Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ccffad25 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

net: convert unicast addr list



This patch converts unicast address list to standard list_head using
previously introduced struct netdev_hw_addr. It also relaxes the
locking. Original spinlock (still used for multicast addresses) is not
needed and is no longer used for a protection of this list. All
reading and writing takes place under rtnl (with no changes).

I also removed a possibility to specify the length of the address
while adding or deleting unicast address. It's always dev->addr_len.

The convertion touched especially e1000 and ixgbe codes when the
change is not so trivial.

Signed-off-by: default avatarJiri Pirko <jpirko@redhat.com>

 drivers/net/bnx2.c               |   13 +--
 drivers/net/e1000/e1000_main.c   |   24 +++--
 drivers/net/ixgbe/ixgbe_common.c |   14 ++--
 drivers/net/ixgbe/ixgbe_common.h |    4 +-
 drivers/net/ixgbe/ixgbe_main.c   |    6 +-
 drivers/net/ixgbe/ixgbe_type.h   |    4 +-
 drivers/net/macvlan.c            |   11 +-
 drivers/net/mv643xx_eth.c        |   11 +-
 drivers/net/niu.c                |    7 +-
 drivers/net/virtio_net.c         |    7 +-
 drivers/s390/net/qeth_l2_main.c  |    6 +-
 drivers/scsi/fcoe/fcoe.c         |   16 ++--
 include/linux/netdevice.h        |   18 ++--
 net/8021q/vlan.c                 |    4 +-
 net/8021q/vlan_dev.c             |   10 +-
 net/core/dev.c                   |  195 +++++++++++++++++++++++++++-----------
 net/dsa/slave.c                  |   10 +-
 net/packet/af_packet.c           |    4 +-
 18 files changed, 227 insertions(+), 137 deletions(-)
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ae63e808
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@
#include <linux/cache.h>
#include <linux/firmware.h>
#include <linux/log2.h>
#include <linux/list.h>

#include "bnx2.h"
#include "bnx2_fw.h"
@@ -3310,7 +3311,7 @@ bnx2_set_rx_mode(struct net_device *dev)
{
	struct bnx2 *bp = netdev_priv(dev);
	u32 rx_mode, sort_mode;
	struct dev_addr_list *uc_ptr;
	struct netdev_hw_addr *ha;
	int i;

	if (!netif_running(dev))
@@ -3369,21 +3370,19 @@ bnx2_set_rx_mode(struct net_device *dev)
		sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN;
	}

	uc_ptr = NULL;
	if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) {
		rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
		sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
			     BNX2_RPM_SORT_USER0_PROM_VLAN;
	} else if (!(dev->flags & IFF_PROMISC)) {
		uc_ptr = dev->uc_list;

		/* Add all entries into to the match filter list */
		for (i = 0; i < dev->uc_count; i++) {
			bnx2_set_mac_addr(bp, uc_ptr->da_addr,
		i = 0;
		list_for_each_entry(ha, &dev->uc_list, list) {
			bnx2_set_mac_addr(bp, ha->addr,
					  i + BNX2_START_UNICAST_ADDRESS_INDEX);
			sort_mode |= (1 <<
				      (i + BNX2_START_UNICAST_ADDRESS_INDEX));
			uc_ptr = uc_ptr->next;
			i++;
		}

	}
+15 −9
Original line number Diff line number Diff line
@@ -2330,7 +2330,8 @@ static void e1000_set_rx_mode(struct net_device *netdev)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;
	struct dev_addr_list *uc_ptr;
	struct netdev_hw_addr *ha;
	bool use_uc = false;
	struct dev_addr_list *mc_ptr;
	u32 rctl;
	u32 hash_value;
@@ -2369,12 +2370,11 @@ static void e1000_set_rx_mode(struct net_device *netdev)
			rctl |= E1000_RCTL_VFE;
	}

	uc_ptr = NULL;
	if (netdev->uc_count > rar_entries - 1) {
		rctl |= E1000_RCTL_UPE;
	} else if (!(netdev->flags & IFF_PROMISC)) {
		rctl &= ~E1000_RCTL_UPE;
		uc_ptr = netdev->uc_list;
		use_uc = true;
	}

	ew32(RCTL, rctl);
@@ -2392,13 +2392,20 @@ static void e1000_set_rx_mode(struct net_device *netdev)
	 * if there are not 14 addresses, go ahead and clear the filters
	 * -- with 82571 controllers only 0-13 entries are filled here
	 */
	i = 1;
	if (use_uc)
		list_for_each_entry(ha, &netdev->uc_list, list) {
			if (i == rar_entries)
				break;
			e1000_rar_set(hw, ha->addr, i++);
		}

	WARN_ON(i == rar_entries);

	mc_ptr = netdev->mc_list;

	for (i = 1; i < rar_entries; i++) {
		if (uc_ptr) {
			e1000_rar_set(hw, uc_ptr->da_addr, i);
			uc_ptr = uc_ptr->next;
		} else if (mc_ptr) {
	for (; i < rar_entries; i++) {
		if (mc_ptr) {
			e1000_rar_set(hw, mc_ptr->da_addr, i);
			mc_ptr = mc_ptr->next;
		} else {
@@ -2408,7 +2415,6 @@ static void e1000_set_rx_mode(struct net_device *netdev)
			E1000_WRITE_FLUSH();
		}
	}
	WARN_ON(uc_ptr != NULL);

	/* load any remaining addresses into the hash table */

+7 −7
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/netdevice.h>

#include "ixgbe.h"
#include "ixgbe_common.h"
@@ -1356,15 +1358,14 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
 *  Drivers using secondary unicast addresses must set user_set_promisc when
 *  manually putting the device into promiscuous mode.
 **/
s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
                              u32 addr_count, ixgbe_mc_addr_itr next)
s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
				      struct list_head *uc_list)
{
	u8 *addr;
	u32 i;
	u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
	u32 uc_addr_in_use;
	u32 fctrl;
	u32 vmdq;
	struct netdev_hw_addr *ha;

	/*
	 * Clear accounting of old secondary address list,
@@ -1382,10 +1383,9 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
	}

	/* Add the new addresses */
	for (i = 0; i < addr_count; i++) {
	list_for_each_entry(ha, uc_list, list) {
		hw_dbg(hw, " Adding the secondary addresses:\n");
		addr = next(hw, &addr_list, &vmdq);
		ixgbe_add_uc_addr(hw, addr, vmdq);
		ixgbe_add_uc_addr(hw, ha->addr, 0);
	}

	if (hw->addr_ctrl.overflow_promisc) {
+2 −2
Original line number Diff line number Diff line
@@ -59,8 +59,8 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw);
s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
                                      u32 mc_addr_count,
                                      ixgbe_mc_addr_itr func);
s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
                                      u32 addr_count, ixgbe_mc_addr_itr func);
s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
				      struct list_head *uc_list);
s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
+1 −5
Original line number Diff line number Diff line
@@ -2181,11 +2181,7 @@ static void ixgbe_set_rx_mode(struct net_device *netdev)
	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);

	/* reprogram secondary unicast list */
	addr_count = netdev->uc_count;
	if (addr_count)
		addr_list = netdev->uc_list->dmi_addr;
	hw->mac.ops.update_uc_addr_list(hw, addr_list, addr_count,
	                                  ixgbe_addr_list_itr);
	hw->mac.ops.update_uc_addr_list(hw, &netdev->uc_list);

	/* reprogram multicast list */
	addr_count = netdev->mc_count;
Loading