Commit 096d19f3 authored by David S. Miller's avatar David S. Miller

Merge branch 'octeontx2-ptp-vf'

Subbaraya Sundeep <sbhatta@marvell.com>

====================
octeontx2: Add PTP support for VFs

PTP is a shared hardware block which can prepend
RX timestamps to packets before directing packets to
PFs or VFs and can notify the TX timestamps to PFs or VFs
via TX completion queue descriptors. Hence adding PTP
support for VFs is exactly similar to PFs with minimal changes.
This patchset adds that PTP support for VFs.

Patch 1 - When an interface is set in promisc/multicast
the same setting is not retained when changing mtu or channels.
This is due to toggling of the interface by driver but not
calling set_rx_mode in the down-up sequence. Since setting
an interface to multicast properly is required for ptp this is
addressed in this patch.

Patch 2 - Changes in VF driver for registering timestamping
ethtool ops and ndo_ioctl.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a365023a 43510ef4
......@@ -730,6 +730,9 @@ static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
int rvu_mbox_handler_cgx_ptp_rx_enable(struct rvu *rvu, struct msg_req *req,
struct msg_rsp *rsp)
{
if (!is_pf_cgxmapped(rvu, rvu_get_pf(req->hdr.pcifunc)))
return -EPERM;
return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, true);
}
......
......@@ -9,6 +9,6 @@ obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o
rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \
otx2_ptp.o otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o \
otx2_devlink.o
rvu_nicvf-y := otx2_vf.o otx2_devlink.o
rvu_nicvf-y := otx2_vf.o otx2_devlink.o otx2_ptp.o
ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af
......@@ -834,6 +834,9 @@ int otx2_open(struct net_device *netdev);
int otx2_stop(struct net_device *netdev);
int otx2_set_real_num_queues(struct net_device *netdev,
int tx_queues, int rx_queues);
int otx2_ioctl(struct net_device *netdev, struct ifreq *req, int cmd);
int otx2_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr);
/* MCAM filter related APIs */
int otx2_mcam_flow_init(struct otx2_nic *pf);
int otx2vf_mcam_flow_init(struct otx2_nic *pfvf);
......
......@@ -1347,6 +1347,7 @@ static const struct ethtool_ops otx2vf_ethtool_ops = {
.get_pauseparam = otx2_get_pauseparam,
.set_pauseparam = otx2_set_pauseparam,
.get_link_ksettings = otx2vf_get_link_ksettings,
.get_ts_info = otx2_get_ts_info,
};
void otx2vf_set_ethtool_ops(struct net_device *netdev)
......
......@@ -1493,6 +1493,44 @@ static void otx2_free_hw_resources(struct otx2_nic *pf)
mutex_unlock(&mbox->lock);
}
static void otx2_do_set_rx_mode(struct otx2_nic *pf)
{
struct net_device *netdev = pf->netdev;
struct nix_rx_mode *req;
bool promisc = false;
if (!(netdev->flags & IFF_UP))
return;
if ((netdev->flags & IFF_PROMISC) ||
(netdev_uc_count(netdev) > OTX2_MAX_UNICAST_FLOWS)) {
promisc = true;
}
/* Write unicast address to mcam entries or del from mcam */
if (!promisc && netdev->priv_flags & IFF_UNICAST_FLT)
__dev_uc_sync(netdev, otx2_add_macfilter, otx2_del_macfilter);
mutex_lock(&pf->mbox.lock);
req = otx2_mbox_alloc_msg_nix_set_rx_mode(&pf->mbox);
if (!req) {
mutex_unlock(&pf->mbox.lock);
return;
}
req->mode = NIX_RX_MODE_UCAST;
if (promisc)
req->mode |= NIX_RX_MODE_PROMISC;
if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST))
req->mode |= NIX_RX_MODE_ALLMULTI;
req->mode |= NIX_RX_MODE_USE_MCE;
otx2_sync_mbox_msg(&pf->mbox);
mutex_unlock(&pf->mbox.lock);
}
int otx2_open(struct net_device *netdev)
{
struct otx2_nic *pf = netdev_priv(netdev);
......@@ -1646,6 +1684,8 @@ int otx2_open(struct net_device *netdev)
if (err)
goto err_tx_stop_queues;
otx2_do_set_rx_mode(pf);
return 0;
err_tx_stop_queues:
......@@ -1791,43 +1831,11 @@ static void otx2_set_rx_mode(struct net_device *netdev)
queue_work(pf->otx2_wq, &pf->rx_mode_work);
}
static void otx2_do_set_rx_mode(struct work_struct *work)
static void otx2_rx_mode_wrk_handler(struct work_struct *work)
{
struct otx2_nic *pf = container_of(work, struct otx2_nic, rx_mode_work);
struct net_device *netdev = pf->netdev;
struct nix_rx_mode *req;
bool promisc = false;
if (!(netdev->flags & IFF_UP))
return;
if ((netdev->flags & IFF_PROMISC) ||
(netdev_uc_count(netdev) > OTX2_MAX_UNICAST_FLOWS)) {
promisc = true;
}
/* Write unicast address to mcam entries or del from mcam */
if (!promisc && netdev->priv_flags & IFF_UNICAST_FLT)
__dev_uc_sync(netdev, otx2_add_macfilter, otx2_del_macfilter);
mutex_lock(&pf->mbox.lock);
req = otx2_mbox_alloc_msg_nix_set_rx_mode(&pf->mbox);
if (!req) {
mutex_unlock(&pf->mbox.lock);
return;
}
req->mode = NIX_RX_MODE_UCAST;
if (promisc)
req->mode |= NIX_RX_MODE_PROMISC;
if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST))
req->mode |= NIX_RX_MODE_ALLMULTI;
req->mode |= NIX_RX_MODE_USE_MCE;
otx2_sync_mbox_msg(&pf->mbox);
mutex_unlock(&pf->mbox.lock);
otx2_do_set_rx_mode(pf);
}
static int otx2_set_features(struct net_device *netdev,
......@@ -1967,7 +1975,7 @@ static int otx2_config_hw_tx_tstamp(struct otx2_nic *pfvf, bool enable)
return 0;
}
static int otx2_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
int otx2_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
{
struct otx2_nic *pfvf = netdev_priv(netdev);
struct hwtstamp_config config;
......@@ -2023,8 +2031,9 @@ static int otx2_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
return copy_to_user(ifr->ifr_data, &config,
sizeof(config)) ? -EFAULT : 0;
}
EXPORT_SYMBOL(otx2_config_hwtstamp);
static int otx2_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
int otx2_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
{
struct otx2_nic *pfvf = netdev_priv(netdev);
struct hwtstamp_config *cfg = &pfvf->tstamp;
......@@ -2039,6 +2048,7 @@ static int otx2_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
return -EOPNOTSUPP;
}
}
EXPORT_SYMBOL(otx2_ioctl);
static int otx2_do_set_vf_mac(struct otx2_nic *pf, int vf, const u8 *mac)
{
......@@ -2358,7 +2368,7 @@ static int otx2_wq_init(struct otx2_nic *pf)
if (!pf->otx2_wq)
return -ENOMEM;
INIT_WORK(&pf->rx_mode_work, otx2_do_set_rx_mode);
INIT_WORK(&pf->rx_mode_work, otx2_rx_mode_wrk_handler);
INIT_WORK(&pf->reset_task, otx2_reset_task);
return 0;
}
......
......@@ -223,6 +223,11 @@ int otx2_ptp_init(struct otx2_nic *pfvf)
struct ptp_req *req;
int err;
if (is_otx2_lbkvf(pfvf->pdev)) {
pfvf->ptp = NULL;
return 0;
}
mutex_lock(&pfvf->mbox.lock);
/* check if PTP block is available */
req = otx2_mbox_alloc_msg_ptp_op(&pfvf->mbox);
......
......@@ -8,9 +8,11 @@
#include <linux/etherdevice.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/net_tstamp.h>
#include "otx2_common.h"
#include "otx2_reg.h"
#include "otx2_ptp.h"
#include "cn10k.h"
#define DRV_NAME "rvu_nicvf"
......@@ -500,6 +502,7 @@ static const struct net_device_ops otx2vf_netdev_ops = {
.ndo_set_features = otx2vf_set_features,
.ndo_get_stats64 = otx2_get_stats64,
.ndo_tx_timeout = otx2_tx_timeout,
.ndo_do_ioctl = otx2_ioctl,
};
static int otx2_wq_init(struct otx2_nic *vf)
......@@ -640,6 +643,9 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto err_detach_rsrc;
/* Don't check for error. Proceed without ptp */
otx2_ptp_init(vf);
/* Assign default mac address */
otx2_get_mac_from_af(netdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment