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

Commit 858aa65c authored by Hariprasad Shenai's avatar Hariprasad Shenai Committed by David S. Miller
Browse files

cxgb4/cxgb4vf: Add set VF mac address support



Add ndo_set_vf_mac support which allows to set the MAC address
for cxgb4vf interfaces from the host

Signed-off-by: default avatarHariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7829451c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1521,4 +1521,7 @@ void t4_idma_monitor_init(struct adapter *adapter,
void t4_idma_monitor(struct adapter *adapter,
		     struct sge_idma_monitor_state *idma,
		     int hz, int ticks);
int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf,
		      unsigned int naddr, u8 *addr);

#endif /* __CXGB4_H__ */
+23 −1
Original line number Diff line number Diff line
@@ -3078,6 +3078,26 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
	return ret;
}

#ifdef CONFIG_PCI_IOV
static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
{
	struct port_info *pi = netdev_priv(dev);
	struct adapter *adap = pi->adapter;

	/* verify MAC addr is valid */
	if (!is_valid_ether_addr(mac)) {
		dev_err(pi->adapter->pdev_dev,
			"Invalid Ethernet address %pM for VF %d\n",
			mac, vf);
		return -EINVAL;
	}

	dev_info(pi->adapter->pdev_dev,
		 "Setting MAC %pM on VF %d\n", mac, vf);
	return t4_set_vf_mac_acl(adap, vf + 1, 1, mac);
}
#endif

static int cxgb_set_mac_addr(struct net_device *dev, void *p)
{
	int ret;
@@ -3136,10 +3156,12 @@ static const struct net_device_ops cxgb4_netdev_ops = {
#ifdef CONFIG_NET_RX_BUSY_POLL
	.ndo_busy_poll        = cxgb_busy_poll,
#endif

};

static const struct net_device_ops cxgb4_mgmt_netdev_ops = {
#ifdef CONFIG_PCI_IOV
	.ndo_set_vf_mac       = cxgb_set_vf_mac,
#endif
};

static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+41 −0
Original line number Diff line number Diff line
@@ -8264,3 +8264,44 @@ void t4_idma_monitor(struct adapter *adapter,
		t4_sge_decode_idma_state(adapter, idma->idma_state[i]);
	}
}

/**
 *	t4_set_vf_mac - Set MAC address for the specified VF
 *	@adapter: The adapter
 *	@vf: one of the VFs instantiated by the specified PF
 *	@naddr: the number of MAC addresses
 *	@addr: the MAC address(es) to be set to the specified VF
 */
int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf,
		      unsigned int naddr, u8 *addr)
{
	struct fw_acl_mac_cmd cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_ACL_MAC_CMD) |
				    FW_CMD_REQUEST_F |
				    FW_CMD_WRITE_F |
				    FW_ACL_MAC_CMD_PFN_V(adapter->pf) |
				    FW_ACL_MAC_CMD_VFN_V(vf));

	/* Note: Do not enable the ACL */
	cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd));
	cmd.nmac = naddr;

	switch (adapter->pf) {
	case 3:
		memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3));
		break;
	case 2:
		memcpy(cmd.macaddr2, addr, sizeof(cmd.macaddr2));
		break;
	case 1:
		memcpy(cmd.macaddr1, addr, sizeof(cmd.macaddr1));
		break;
	case 0:
		memcpy(cmd.macaddr0, addr, sizeof(cmd.macaddr0));
		break;
	}

	return t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &cmd);
}
+24 −0
Original line number Diff line number Diff line
@@ -2777,6 +2777,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
	struct adapter *adapter;
	struct port_info *pi;
	struct net_device *netdev;
	unsigned int pf;

	/*
	 * Print our driver banner the first time we're called to initialize a
@@ -2903,8 +2904,11 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
	 * Allocate our "adapter ports" and stitch everything together.
	 */
	pmask = adapter->params.vfres.pmask;
	pf = t4vf_get_pf_from_vf(adapter);
	for_each_port(adapter, pidx) {
		int port_id, viid;
		u8 mac[ETH_ALEN];
		unsigned int naddr = 1;

		/*
		 * We simplistically allocate our virtual interfaces
@@ -2975,6 +2979,26 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
				pidx);
			goto err_free_dev;
		}

		err = t4vf_get_vf_mac_acl(adapter, pf, &naddr, mac);
		if (err) {
			dev_err(&pdev->dev,
				"unable to determine MAC ACL address, "
				"continuing anyway.. (status %d)\n", err);
		} else if (naddr && adapter->params.vfres.nvi == 1) {
			struct sockaddr addr;

			ether_addr_copy(addr.sa_data, mac);
			err = cxgb4vf_set_mac_addr(netdev, &addr);
			if (err) {
				dev_err(&pdev->dev,
					"unable to set MAC address %pM\n",
					mac);
				goto err_free_dev;
			}
			dev_info(&pdev->dev,
				 "Using assigned MAC ACL: %pM\n", mac);
		}
	}

	/* See what interrupts we'll be using.  If we've been configured to
+3 −0
Original line number Diff line number Diff line
@@ -347,6 +347,7 @@ int t4vf_bar2_sge_qregs(struct adapter *adapter,
			u64 *pbar2_qoffset,
			unsigned int *pbar2_qid);

unsigned int t4vf_get_pf_from_vf(struct adapter *);
int t4vf_get_sge_params(struct adapter *);
int t4vf_get_vpd_params(struct adapter *);
int t4vf_get_dev_params(struct adapter *);
@@ -381,5 +382,7 @@ int t4vf_eth_eq_free(struct adapter *, unsigned int);

int t4vf_handle_fw_rpl(struct adapter *, const __be64 *);
int t4vf_prep_adapter(struct adapter *);
int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf,
			unsigned int *naddr, u8 *addr);

#endif /* __T4VF_COMMON_H__ */
Loading