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

Commit 46ec20ff authored by Greg Rose's avatar Greg Rose Committed by Jeff Kirsher
Browse files

ixgbevf: Add macvlan support in the set rx mode op



Implement setup of unicast address list in the VF driver's set_rx_mode
netdev op.  Unicast addresses are sent to the PF via a mailbox message
and the PF will check if it has room in the RAR table and if so set the
filter for the VF.

Signed-off-by: default avatarGreg Rose <gregory.v.rose@intel.com>
Tested-by: default avatarSibai Li <sibai.li@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent d64a6f4d
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -1460,6 +1460,34 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter)
	}
}

static int ixgbevf_write_uc_addr_list(struct net_device *netdev)
{
	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
	struct ixgbe_hw *hw = &adapter->hw;
	int count = 0;

	if ((netdev_uc_count(netdev)) > 10) {
		printk(KERN_ERR "Too many unicast filters - No Space\n");
		return -ENOSPC;
	}

	if (!netdev_uc_empty(netdev)) {
		struct netdev_hw_addr *ha;
		netdev_for_each_uc_addr(ha, netdev) {
			hw->mac.ops.set_uc_addr(hw, ++count, ha->addr);
			udelay(200);
		}
	} else {
		/*
		 * If the list is empty then send message to PF driver to
		 * clear all macvlans on this VF.
		 */
		hw->mac.ops.set_uc_addr(hw, 0, NULL);
	}

	return count;
}

/**
 * ixgbevf_set_rx_mode - Multicast set
 * @netdev: network interface device structure
@@ -1476,6 +1504,8 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev)
	/* reprogram multicast list */
	if (hw->mac.ops.update_mc_addr_list)
		hw->mac.ops.update_mc_addr_list(hw, netdev);

	ixgbevf_write_uc_addr_list(netdev);
}

static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
+1 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@
#define IXGBE_VF_SET_MULTICAST    0x03 /* VF requests PF to set MC addr */
#define IXGBE_VF_SET_VLAN         0x04 /* VF requests PF to set VLAN */
#define IXGBE_VF_SET_LPE          0x05 /* VF requests PF to set VMOLR.LPE */
#define IXGBE_VF_SET_MACVLAN      0x06 /* VF requests PF for unicast filter */

/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
+34 −0
Original line number Diff line number Diff line
@@ -216,6 +216,39 @@ static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
	return 0;
}

static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
{
	struct ixgbe_mbx_info *mbx = &hw->mbx;
	u32 msgbuf[3];
	u8 *msg_addr = (u8 *)(&msgbuf[1]);
	s32 ret_val;

	memset(msgbuf, 0, sizeof(msgbuf));
	/*
	 * If index is one then this is the start of a new list and needs
	 * indication to the PF so it can do it's own list management.
	 * If it is zero then that tells the PF to just clear all of
	 * this VF's macvlans and there is no new list.
	 */
	msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
	msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
	if (addr)
		memcpy(msg_addr, addr, 6);
	ret_val = mbx->ops.write_posted(hw, msgbuf, 3);

	if (!ret_val)
		ret_val = mbx->ops.read_posted(hw, msgbuf, 3);

	msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;

	if (!ret_val)
		if (msgbuf[0] ==
		    (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK))
			ret_val = -ENOMEM;

	return ret_val;
}

/**
 *  ixgbevf_set_rar_vf - set device MAC address
 *  @hw: pointer to hardware structure
@@ -378,6 +411,7 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = {
	.check_link          = ixgbevf_check_mac_link_vf,
	.set_rar             = ixgbevf_set_rar_vf,
	.update_mc_addr_list = ixgbevf_update_mc_addr_list_vf,
	.set_uc_addr         = ixgbevf_set_uc_addr_vf,
	.set_vfta            = ixgbevf_set_vfta_vf,
};

+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ struct ixgbe_mac_operations {

	/* RAR, Multicast, VLAN */
	s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32);
	s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *);
	s32 (*init_rx_addrs)(struct ixgbe_hw *);
	s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *);
	s32 (*enable_mc)(struct ixgbe_hw *);