mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
nvethernet: Add FRP command IOCTL support
Add new private IOCTL to perform Flexible Receive Parser table entry add, delete, and update operations using OSI API call. Bug 200565623 Change-Id: I00f2be1aaa6ee737de5154085be0521db0bb9593 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2331371 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com>
This commit is contained in:
committed by
Revanth Kumar Uppala
parent
f244049a90
commit
c2f3c724bd
@@ -43,6 +43,7 @@ nvethernet-objs:= ether_linux.o \
|
||||
$(OSI_DMA)/eqos_desc.o \
|
||||
$(OSI_DMA)/mgbe_desc.o \
|
||||
$(OSI_CORE)/mgbe_mmc.o \
|
||||
$(OSI_CORE)/frp.o \
|
||||
$(OSI_CORE)/vlan_filter.o
|
||||
|
||||
nvethernet-$(CONFIG_NVETHERNET_SELFTESTS) += selftests.o
|
||||
|
||||
@@ -39,6 +39,35 @@ struct ether_stats {
|
||||
size_t stat_offset;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Name of FRP statistics, with length of name not more than
|
||||
* ETH_GSTRING_LEN
|
||||
*/
|
||||
#if KERNEL_VERSION(5, 5, 0) > LINUX_VERSION_CODE
|
||||
#define ETHER_PKT_FRP_STAT(y) \
|
||||
{ (#y), FIELD_SIZEOF(struct osi_pkt_err_stats, y), \
|
||||
offsetof(struct osi_dma_priv_data, pkt_err_stats.y)}
|
||||
#else
|
||||
#define ETHER_PKT_FRP_STAT(y) \
|
||||
{ (#y), sizeof_field(struct osi_pkt_err_stats, y), \
|
||||
offsetof(struct osi_dma_priv_data, pkt_err_stats.y)}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief FRP statistics
|
||||
*/
|
||||
static const struct ether_stats ether_frpstrings_stats[] = {
|
||||
ETHER_PKT_FRP_STAT(frp_parsed),
|
||||
ETHER_PKT_FRP_STAT(frp_dropped),
|
||||
ETHER_PKT_FRP_STAT(frp_err),
|
||||
ETHER_PKT_FRP_STAT(frp_incomplete),
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Ethernet FRP statistics array length
|
||||
*/
|
||||
#define ETHER_FRP_STAT_LEN OSI_ARRAY_SIZE(ether_frpstrings_stats)
|
||||
|
||||
/**
|
||||
* @brief Name of pkt_err statistics, with length of name not more than
|
||||
* ETH_GSTRING_LEN
|
||||
@@ -496,6 +525,15 @@ static void ether_get_ethtool_stats(struct net_device *dev,
|
||||
data[j++] = (ether_tstrings_stats[i].sizeof_stat ==
|
||||
sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
|
||||
}
|
||||
|
||||
for (i = 0; ((i < ETHER_FRP_STAT_LEN) &&
|
||||
(pdata->hw_feat.frp_sel == OSI_ENABLE)); i++) {
|
||||
char *p = (char *)osi_core +
|
||||
ether_frpstrings_stats[i].stat_offset;
|
||||
|
||||
data[j++] = (ether_frpstrings_stats[i].sizeof_stat ==
|
||||
sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,6 +584,13 @@ static int ether_get_sset_count(struct net_device *dev, int sset)
|
||||
len += ETHER_EXTRA_TSN_STAT_LEN;
|
||||
}
|
||||
}
|
||||
if (INT_MAX - ETHER_FRP_STAT_LEN < len) {
|
||||
/* do nothing */
|
||||
} else {
|
||||
if (pdata->hw_feat.frp_sel == OSI_ENABLE) {
|
||||
len += ETHER_FRP_STAT_LEN;
|
||||
}
|
||||
}
|
||||
} else if (sset == ETH_SS_TEST) {
|
||||
len = ether_selftest_get_count(pdata);
|
||||
} else {
|
||||
@@ -619,6 +664,17 @@ static void ether_get_strings(struct net_device *dev, u32 stringset, u8 *data)
|
||||
}
|
||||
p += ETH_GSTRING_LEN;
|
||||
}
|
||||
for (i = 0; ((i < ETHER_FRP_STAT_LEN) &&
|
||||
(pdata->hw_feat.frp_sel == OSI_ENABLE));
|
||||
i++) {
|
||||
str = (u8 *)
|
||||
ether_frpstrings_stats[i].stat_string;
|
||||
if (memcpy(p, str, ETH_GSTRING_LEN) ==
|
||||
OSI_NULL) {
|
||||
return;
|
||||
}
|
||||
p += ETH_GSTRING_LEN;
|
||||
}
|
||||
}
|
||||
} else if (stringset == (u32)ETH_SS_TEST) {
|
||||
ether_selftest_get_strings(pdata, p);
|
||||
|
||||
@@ -256,6 +256,48 @@ static int ether_config_arp_offload(struct ether_priv_data *pdata,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is invoked by ioctl function when user issues an ioctl
|
||||
* command to configure Flexible Receive Parser table entry add, delete, and
|
||||
* update commands.
|
||||
*
|
||||
* @param[in] dev: Pointer to net device structure.
|
||||
* @param[in] ifdata: pointer to IOCTL specific structure.
|
||||
*
|
||||
* @note MAC and PHY need to be initialized.
|
||||
*
|
||||
* @retval 0 on Success
|
||||
* @retval "negative value" on Failure
|
||||
*/
|
||||
static int ether_config_frp_cmd(struct net_device *dev,
|
||||
struct ether_ifr_data *ifdata)
|
||||
{
|
||||
struct ether_priv_data *pdata = netdev_priv(dev);
|
||||
struct osi_core_priv_data *osi_core = pdata->osi_core;
|
||||
struct osi_core_frp_cmd frp_cmd;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (pdata->hw_feat.frp_sel == OSI_DISABLE) {
|
||||
dev_err(pdata->dev, "MAC doen't support FRP\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!ifdata->ptr) {
|
||||
dev_err(pdata->dev, "%s: Invalid data for priv ioctl %d\n",
|
||||
__func__, ifdata->ifcmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (copy_from_user(&frp_cmd,
|
||||
(struct osi_core_frp_cmd *)ifdata->ptr,
|
||||
sizeof(struct osi_core_frp_cmd)) != 0U) {
|
||||
dev_err(pdata->dev, "%s copy from user failed\n", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return osi_configure_frp(osi_core, &frp_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is invoked by ioctl when user issues an ioctl command
|
||||
* to enable/disable L3/L4 filtering.
|
||||
@@ -910,6 +952,9 @@ int ether_handle_priv_ioctl(struct net_device *ndev,
|
||||
ret = -EOPNOTSUPP;
|
||||
}
|
||||
break;
|
||||
case ETHER_CONFIG_FRP_CMD:
|
||||
ret = ether_config_frp_cmd(ndev, &ifdata);
|
||||
break;
|
||||
case EQOS_IPV4_FILTERING_CMD:
|
||||
ret = ether_config_ip4_filters(ndev, &ifdata);
|
||||
break;
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
#define ETHER_PTP_RXQUEUE 48
|
||||
#define ETHER_CONFIG_EST 49
|
||||
#define ETHER_CONFIG_FPE 50
|
||||
/* FRP Command */
|
||||
#define ETHER_CONFIG_FRP_CMD 51
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
||||
@@ -121,6 +121,49 @@ static DEVICE_ATTR(mac_loopback, (S_IRUGO | S_IWUSR),
|
||||
ether_mac_loopback_show,
|
||||
ether_mac_loopback_store);
|
||||
|
||||
/**
|
||||
* @brief Shows the current setting of FRP Table
|
||||
*
|
||||
* Algorithm: Display the FRP table
|
||||
*
|
||||
* @param[in] dev: Device data.
|
||||
* @param[in] attr: Device attribute
|
||||
* @param[in] buf: Buffer to store the current MAC loopback setting
|
||||
*
|
||||
* @note MAC and PHY need to be initialized.
|
||||
*/
|
||||
static ssize_t ether_mac_frp_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct osi_core_priv_data *osi_core = pdata->osi_core;
|
||||
struct osi_core_frp_entry *entry = NULL;
|
||||
struct osi_core_frp_data *data = NULL;
|
||||
int i = 0, j = 0;
|
||||
|
||||
/* Write FRP table entries */
|
||||
for (i = 0, j = 0; ((i < osi_core->frp_cnt) && (j < PAGE_SIZE)); i++) {
|
||||
entry = &osi_core->frp_table[i];
|
||||
data = &entry->data;
|
||||
j += scnprintf((buf + j), (PAGE_SIZE - j),
|
||||
"[%d] ID:%d MD:0x%x ME:0x%x AF:%d RF:%d IM:%d NIC:%d FO:%d OKI:%d DCH:x%x\n",
|
||||
i, entry->frp_id, data->match_data,
|
||||
data->match_en, data->accept_frame,
|
||||
data->reject_frame, data->inverse_match,
|
||||
data->next_ins_ctrl, data->frame_offset,
|
||||
data->ok_index, data->dma_chsel);
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sysfs attribute for FRP table show
|
||||
*
|
||||
*/
|
||||
static DEVICE_ATTR(frp, 0644, ether_mac_frp_show, NULL);
|
||||
|
||||
/**
|
||||
* @brief Shows the current setting of PTP mode
|
||||
*
|
||||
@@ -275,6 +318,7 @@ static struct attribute *ether_sysfs_attrs[] = {
|
||||
&dev_attr_mac_loopback.attr,
|
||||
&dev_attr_ptp_mode.attr,
|
||||
&dev_attr_ptp_sync.attr,
|
||||
&dev_attr_frp.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user