diff options
author | Yuval Mintz <Yuval.Mintz@qlogic.com> | 2016-05-11 16:36:21 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-12 07:04:08 +0300 |
commit | eff169608c250193e72089dc4ab15cb79e0bd68c (patch) | |
tree | 1e2c0fef7a427954be8800ee21914e34a6c61d87 /drivers/net/ethernet/qlogic/qede | |
parent | 08feecd7fc709077ce92d21a979f522a5f57170a (diff) | |
download | linux-eff169608c250193e72089dc4ab15cb79e0bd68c.tar.xz |
qed*: Support forced MAC
Allows the PF to enforce the VF's mac.
i.e., by using `ip link ... vf <x> mac <value>'.
While a MAC is forced, PF would prevent the VF from configuring any other
MAC.
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qede')
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_main.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index 4d59d7e00e42..b326b15d5196 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -118,6 +118,22 @@ static int qede_set_vf_vlan(struct net_device *ndev, int vf, u16 vlan, u8 qos) return edev->ops->iov->set_vlan(edev->cdev, vlan, vf); } +static int qede_set_vf_mac(struct net_device *ndev, int vfidx, u8 *mac) +{ + struct qede_dev *edev = netdev_priv(ndev); + + DP_VERBOSE(edev, QED_MSG_IOV, + "Setting MAC %02x:%02x:%02x:%02x:%02x:%02x to VF [%d]\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], vfidx); + + if (!is_valid_ether_addr(mac)) { + DP_VERBOSE(edev, QED_MSG_IOV, "MAC address isn't valid\n"); + return -EINVAL; + } + + return edev->ops->iov->set_mac(edev->cdev, mac, vfidx); +} + static int qede_sriov_configure(struct pci_dev *pdev, int num_vfs_param) { struct qede_dev *edev = netdev_priv(pci_get_drvdata(pdev)); @@ -138,10 +154,19 @@ static struct pci_driver qede_pci_driver = { #endif }; +static void qede_force_mac(void *dev, u8 *mac) +{ + struct qede_dev *edev = dev; + + ether_addr_copy(edev->ndev->dev_addr, mac); + ether_addr_copy(edev->primary_mac, mac); +} + static struct qed_eth_cb_ops qede_ll_ops = { { .link_update = qede_link_update, }, + .force_mac = qede_force_mac, }; static int qede_netdev_event(struct notifier_block *this, unsigned long event, @@ -2087,6 +2112,7 @@ static const struct net_device_ops qede_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = qede_change_mtu, #ifdef CONFIG_QED_SRIOV + .ndo_set_vf_mac = qede_set_vf_mac, .ndo_set_vf_vlan = qede_set_vf_vlan, #endif .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid, @@ -3512,6 +3538,11 @@ static int qede_set_mac_addr(struct net_device *ndev, void *p) return -EFAULT; } + if (!edev->ops->check_mac(edev->cdev, addr->sa_data)) { + DP_NOTICE(edev, "qed prevents setting MAC\n"); + return -EINVAL; + } + ether_addr_copy(ndev->dev_addr, addr->sa_data); if (!netif_running(ndev)) { |