octeontx2-pf: Add TC feature for VFs
This patch adds TC feature for VFs also. When MCAM rules are allocated for a VF then either TC or ntuple filters can be used. Below are the commands to use TC feature for a VF(say lbk0): devlink dev param set pci/0002:01:00.1 name mcam_count value 16 \ cmode runtime ethtool -K lbk0 hw-tc-offload on ifconfig lbk0 up tc qdisc add dev lbk0 ingress tc filter add dev lbk0 parent ffff: protocol ip flower skip_sw \ dst_mac 98:03:9b:83:aa:12 action police rate 100Mbit burst 5000 Also to modify any fields of the hardware context with NIX_AQ_INSTOP_WRITE command then corresponding masks of those fields must be set as per hardware. This was missing in ingress ratelimiting context. This patch sets those masks also. Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com> Signed-off-by: Sunil Goutham <sgoutham@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ede6c39c4f
commit
4b0385bc8e
@ -5312,6 +5312,7 @@ int rvu_nix_setup_ratelimit_aggr(struct rvu *rvu, u16 pcifunc,
|
||||
aq_req.ctype = NIX_AQ_CTYPE_BANDPROF;
|
||||
aq_req.op = NIX_AQ_INSTOP_WRITE;
|
||||
memcpy(&aq_req.prof, &aq_rsp.prof, sizeof(struct nix_bandprof_s));
|
||||
memset((char *)&aq_req.prof_mask, 0xff, sizeof(struct nix_bandprof_s));
|
||||
/* Clear higher layer enable bit in the mid profile, just in case */
|
||||
aq_req.prof.hl_en = 0;
|
||||
aq_req.prof_mask.hl_en = 1;
|
||||
|
@ -1727,6 +1727,56 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_get_max_mtu);
|
||||
|
||||
int otx2_handle_ntuple_tc_features(struct net_device *netdev, netdev_features_t features)
|
||||
{
|
||||
netdev_features_t changed = features ^ netdev->features;
|
||||
struct otx2_nic *pfvf = netdev_priv(netdev);
|
||||
bool ntuple = !!(features & NETIF_F_NTUPLE);
|
||||
bool tc = !!(features & NETIF_F_HW_TC);
|
||||
|
||||
if ((changed & NETIF_F_NTUPLE) && !ntuple)
|
||||
otx2_destroy_ntuple_flows(pfvf);
|
||||
|
||||
if ((changed & NETIF_F_NTUPLE) && ntuple) {
|
||||
if (!pfvf->flow_cfg->max_flows) {
|
||||
netdev_err(netdev,
|
||||
"Can't enable NTUPLE, MCAM entries not allocated\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_HW_TC) && tc) {
|
||||
if (!pfvf->flow_cfg->max_flows) {
|
||||
netdev_err(netdev,
|
||||
"Can't enable TC, MCAM entries not allocated\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_HW_TC) && !tc &&
|
||||
pfvf->flow_cfg && pfvf->flow_cfg->nr_flows) {
|
||||
netdev_err(netdev, "Can't disable TC hardware offload while flows are active\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_NTUPLE) && ntuple &&
|
||||
(netdev->features & NETIF_F_HW_TC) && !(changed & NETIF_F_HW_TC)) {
|
||||
netdev_err(netdev,
|
||||
"Can't enable NTUPLE when TC is active, disable TC and retry\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_HW_TC) && tc &&
|
||||
(netdev->features & NETIF_F_NTUPLE) && !(changed & NETIF_F_NTUPLE)) {
|
||||
netdev_err(netdev,
|
||||
"Can't enable TC when NTUPLE is active, disable NTUPLE and retry\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_handle_ntuple_tc_features);
|
||||
|
||||
#define M(_name, _id, _fn_name, _req_type, _rsp_type) \
|
||||
int __weak \
|
||||
otx2_mbox_up_handler_ ## _fn_name(struct otx2_nic *pfvf, \
|
||||
|
@ -871,6 +871,8 @@ int otx2_enable_rxvlan(struct otx2_nic *pf, bool enable);
|
||||
int otx2_install_rxvlan_offload_flow(struct otx2_nic *pfvf);
|
||||
bool otx2_xdp_sq_append_pkt(struct otx2_nic *pfvf, u64 iova, int len, u16 qidx);
|
||||
u16 otx2_get_max_mtu(struct otx2_nic *pfvf);
|
||||
int otx2_handle_ntuple_tc_features(struct net_device *netdev,
|
||||
netdev_features_t features);
|
||||
/* tc support */
|
||||
int otx2_init_tc(struct otx2_nic *nic);
|
||||
void otx2_shutdown_tc(struct otx2_nic *nic);
|
||||
|
@ -1863,9 +1863,7 @@ static int otx2_set_features(struct net_device *netdev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
netdev_features_t changed = features ^ netdev->features;
|
||||
bool ntuple = !!(features & NETIF_F_NTUPLE);
|
||||
struct otx2_nic *pf = netdev_priv(netdev);
|
||||
bool tc = !!(features & NETIF_F_HW_TC);
|
||||
|
||||
if ((changed & NETIF_F_LOOPBACK) && netif_running(netdev))
|
||||
return otx2_cgx_config_loopback(pf,
|
||||
@ -1875,46 +1873,7 @@ static int otx2_set_features(struct net_device *netdev,
|
||||
return otx2_enable_rxvlan(pf,
|
||||
features & NETIF_F_HW_VLAN_CTAG_RX);
|
||||
|
||||
if ((changed & NETIF_F_NTUPLE) && !ntuple)
|
||||
otx2_destroy_ntuple_flows(pf);
|
||||
|
||||
if ((changed & NETIF_F_NTUPLE) && ntuple) {
|
||||
if (!pf->flow_cfg->max_flows) {
|
||||
netdev_err(netdev,
|
||||
"Can't enable NTUPLE, MCAM entries not allocated\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_HW_TC) && tc) {
|
||||
if (!pf->flow_cfg->max_flows) {
|
||||
netdev_err(netdev,
|
||||
"Can't enable TC, MCAM entries not allocated\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_HW_TC) && !tc &&
|
||||
pf->flow_cfg && pf->flow_cfg->nr_flows) {
|
||||
netdev_err(netdev, "Can't disable TC hardware offload while flows are active\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_NTUPLE) && ntuple &&
|
||||
(netdev->features & NETIF_F_HW_TC) && !(changed & NETIF_F_HW_TC)) {
|
||||
netdev_err(netdev,
|
||||
"Can't enable NTUPLE when TC is active, disable TC and retry\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_HW_TC) && tc &&
|
||||
(netdev->features & NETIF_F_NTUPLE) && !(changed & NETIF_F_NTUPLE)) {
|
||||
netdev_err(netdev,
|
||||
"Can't enable TC when NTUPLE is active, disable NTUPLE and retry\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return otx2_handle_ntuple_tc_features(netdev, features);
|
||||
}
|
||||
|
||||
static void otx2_reset_task(struct work_struct *work)
|
||||
|
@ -58,7 +58,7 @@ int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic)
|
||||
{
|
||||
struct otx2_tc_info *tc = &nic->tc_info;
|
||||
|
||||
if (!nic->flow_cfg->max_flows || is_otx2_vf(nic->pcifunc))
|
||||
if (!nic->flow_cfg->max_flows)
|
||||
return 0;
|
||||
|
||||
/* Max flows changed, free the existing bitmap */
|
||||
@ -1023,6 +1023,7 @@ int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_setup_tc);
|
||||
|
||||
static const struct rhashtable_params tc_flow_ht_params = {
|
||||
.head_offset = offsetof(struct otx2_tc_flow, node),
|
||||
@ -1052,6 +1053,7 @@ int otx2_init_tc(struct otx2_nic *nic)
|
||||
tc->flow_ht_params = tc_flow_ht_params;
|
||||
return rhashtable_init(&tc->flow_table, &tc->flow_ht_params);
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_init_tc);
|
||||
|
||||
void otx2_shutdown_tc(struct otx2_nic *nic)
|
||||
{
|
||||
@ -1060,3 +1062,4 @@ void otx2_shutdown_tc(struct otx2_nic *nic)
|
||||
kfree(tc->tc_entries_bitmap);
|
||||
rhashtable_destroy(&tc->flow_table);
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_shutdown_tc);
|
||||
|
@ -472,23 +472,7 @@ static void otx2vf_reset_task(struct work_struct *work)
|
||||
static int otx2vf_set_features(struct net_device *netdev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
netdev_features_t changed = features ^ netdev->features;
|
||||
bool ntuple_enabled = !!(features & NETIF_F_NTUPLE);
|
||||
struct otx2_nic *vf = netdev_priv(netdev);
|
||||
|
||||
if (changed & NETIF_F_NTUPLE) {
|
||||
if (!ntuple_enabled) {
|
||||
otx2_mcam_flow_del(vf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!otx2_get_maxflows(vf->flow_cfg)) {
|
||||
netdev_err(netdev,
|
||||
"Can't enable NTUPLE, MCAM entries not allocated\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return otx2_handle_ntuple_tc_features(netdev, features);
|
||||
}
|
||||
|
||||
static const struct net_device_ops otx2vf_netdev_ops = {
|
||||
@ -502,6 +486,7 @@ static const struct net_device_ops otx2vf_netdev_ops = {
|
||||
.ndo_get_stats64 = otx2_get_stats64,
|
||||
.ndo_tx_timeout = otx2_tx_timeout,
|
||||
.ndo_eth_ioctl = otx2_ioctl,
|
||||
.ndo_setup_tc = otx2_setup_tc,
|
||||
};
|
||||
|
||||
static int otx2_wq_init(struct otx2_nic *vf)
|
||||
@ -663,6 +648,7 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
||||
netdev->hw_features |= NETIF_F_NTUPLE;
|
||||
netdev->hw_features |= NETIF_F_RXALL;
|
||||
netdev->hw_features |= NETIF_F_HW_TC;
|
||||
|
||||
netif_set_gso_max_segs(netdev, OTX2_MAX_GSO_SEGS);
|
||||
netdev->watchdog_timeo = OTX2_TX_TIMEOUT;
|
||||
@ -698,18 +684,24 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
if (err)
|
||||
goto err_unreg_netdev;
|
||||
|
||||
err = otx2_register_dl(vf);
|
||||
err = otx2_init_tc(vf);
|
||||
if (err)
|
||||
goto err_unreg_netdev;
|
||||
|
||||
err = otx2_register_dl(vf);
|
||||
if (err)
|
||||
goto err_shutdown_tc;
|
||||
|
||||
#ifdef CONFIG_DCB
|
||||
err = otx2_dcbnl_set_ops(netdev);
|
||||
if (err)
|
||||
goto err_unreg_netdev;
|
||||
goto err_shutdown_tc;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
err_shutdown_tc:
|
||||
otx2_shutdown_tc(vf);
|
||||
err_unreg_netdev:
|
||||
unregister_netdev(netdev);
|
||||
err_ptp_destroy:
|
||||
|
Loading…
Reference in New Issue
Block a user