Commit cb55ff7a authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'add-support-for-lan966x-is2-vcap'

Horatiu Vultur says:

====================
Add support for lan966x IS2 VCAP

This provides initial support for lan966x for 'tc' traffic control
userspace tool and its flower filter. For this is required to use
the VCAP library.

Currently supported flower filter keys and actions are:
- source and destination MAC address keys
- trap action
====================

Link: https://lore.kernel.org/r/20221125095010.124458-1-horatiu.vultur@microchip.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 7a168f56 4f141e36
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,5 +8,6 @@ config LAN966X_SWITCH
	select PHYLINK
	select PACKING
	select PAGE_POOL
	select VCAP
	help
	  This driver supports the Lan966x network switch device.
+5 −1
Original line number Diff line number Diff line
@@ -12,4 +12,8 @@ lan966x-switch-objs := lan966x_main.o lan966x_phylink.o lan966x_port.o \
			lan966x_tc.o lan966x_mqprio.o lan966x_taprio.o \
			lan966x_tbf.o lan966x_cbs.o lan966x_ets.o \
			lan966x_tc_matchall.o lan966x_police.o lan966x_mirror.o \
			lan966x_xdp.o
			lan966x_xdp.o lan966x_vcap_impl.o lan966x_vcap_ag_api.o \
			lan966x_tc_flower.o lan966x_goto.o

# Provide include files
ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap
+54 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0+

#include "lan966x_main.h"
#include "vcap_api_client.h"

int lan966x_goto_port_add(struct lan966x_port *port,
			  struct flow_action_entry *act,
			  unsigned long goto_id,
			  struct netlink_ext_ack *extack)
{
	struct lan966x *lan966x = port->lan966x;
	int err;

	err = vcap_enable_lookups(lan966x->vcap_ctrl, port->dev,
				  act->chain_index, goto_id,
				  true);
	if (err == -EFAULT) {
		NL_SET_ERR_MSG_MOD(extack, "Unsupported goto chain");
		return -EOPNOTSUPP;
	}

	if (err == -EADDRINUSE) {
		NL_SET_ERR_MSG_MOD(extack, "VCAP already enabled");
		return -EOPNOTSUPP;
	}

	if (err) {
		NL_SET_ERR_MSG_MOD(extack, "Could not enable VCAP lookups");
		return err;
	}

	port->tc.goto_id = goto_id;

	return 0;
}

int lan966x_goto_port_del(struct lan966x_port *port,
			  unsigned long goto_id,
			  struct netlink_ext_ack *extack)
{
	struct lan966x *lan966x = port->lan966x;
	int err;

	err = vcap_enable_lookups(lan966x->vcap_ctrl, port->dev, 0,
				  goto_id, false);
	if (err) {
		NL_SET_ERR_MSG_MOD(extack, "Could not disable VCAP lookups");
		return err;
	}

	port->tc.goto_id = 0;

	return 0;
}
+11 −0
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ static const struct lan966x_main_io_resource lan966x_main_iomap[] = {
	{ TARGET_PTP,                    0xc000, 1 }, /* 0xe200c000 */
	{ TARGET_CHIP_TOP,              0x10000, 1 }, /* 0xe2010000 */
	{ TARGET_REW,                   0x14000, 1 }, /* 0xe2014000 */
	{ TARGET_VCAP,                  0x18000, 1 }, /* 0xe2018000 */
	{ TARGET_VCAP + 1,              0x20000, 1 }, /* 0xe2020000 */
	{ TARGET_VCAP + 2,              0x24000, 1 }, /* 0xe2024000 */
	{ TARGET_SYS,                   0x28000, 1 }, /* 0xe2028000 */
	{ TARGET_DEV,                   0x34000, 1 }, /* 0xe2034000 */
	{ TARGET_DEV +  1,              0x38000, 1 }, /* 0xe2038000 */
@@ -1157,8 +1160,15 @@ static int lan966x_probe(struct platform_device *pdev)
	if (err)
		goto cleanup_ptp;

	err = lan966x_vcap_init(lan966x);
	if (err)
		goto cleanup_fdma;

	return 0;

cleanup_fdma:
	lan966x_fdma_deinit(lan966x);

cleanup_ptp:
	lan966x_ptp_deinit(lan966x);

@@ -1182,6 +1192,7 @@ static int lan966x_remove(struct platform_device *pdev)
	struct lan966x *lan966x = platform_get_drvdata(pdev);

	lan966x_taprio_deinit(lan966x);
	lan966x_vcap_deinit(lan966x);
	lan966x_fdma_deinit(lan966x);
	lan966x_cleanup_ports(lan966x);

+18 −0
Original line number Diff line number Diff line
@@ -300,6 +300,9 @@ struct lan966x {
	struct lan966x_port *mirror_monitor;
	u32 mirror_mask[2];
	u32 mirror_count;

	/* vcap */
	struct vcap_control *vcap_ctrl;
};

struct lan966x_port_config {
@@ -317,6 +320,7 @@ struct lan966x_port_tc {
	unsigned long police_id;
	unsigned long ingress_mirror_id;
	unsigned long egress_mirror_id;
	unsigned long goto_id;
	struct flow_stats police_stat;
	struct flow_stats mirror_stat;
};
@@ -582,6 +586,20 @@ static inline bool lan966x_xdp_port_present(struct lan966x_port *port)
	return !!port->xdp_prog;
}

int lan966x_vcap_init(struct lan966x *lan966x);
void lan966x_vcap_deinit(struct lan966x *lan966x);

int lan966x_tc_flower(struct lan966x_port *port,
		      struct flow_cls_offload *f);

int lan966x_goto_port_add(struct lan966x_port *port,
			  struct flow_action_entry *act,
			  unsigned long goto_id,
			  struct netlink_ext_ack *extack);
int lan966x_goto_port_del(struct lan966x_port *port,
			  unsigned long goto_id,
			  struct netlink_ext_ack *extack);

static inline void __iomem *lan_addr(void __iomem *base[],
				     int id, int tinst, int tcnt,
				     int gbase, int ginst,
Loading