Commit 4b0385bc authored by Subbaraya Sundeep's avatar Subbaraya Sundeep Committed by David S. Miller
Browse files

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: default avatarSubbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: default avatarSunil Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ede6c39c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;
+50 −0
Original line number Diff line number Diff line
@@ -1727,6 +1727,56 @@ u16 otx2_get_max_mtu(struct otx2_nic *pfvf)
}
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,		\
+2 −0
Original line number Diff line number Diff line
@@ -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);
+1 −42
Original line number Diff line number Diff line
@@ -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)
+4 −1
Original line number Diff line number Diff line
@@ -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);
Loading