123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671 |
- From 36b446d44d66a6d6a072d3f5e87ebb05e0b88d98 Mon Sep 17 00:00:00 2001
- From: Xiaoliang Yang <[email protected]>
- Date: Fri, 29 Nov 2019 14:28:37 +0800
- Subject: [PATCH] net: dsa: ocelot: add tsn support for felix switch
- Support tsn capabilities in DSA felix switch driver. This felix tsn
- driver is using tsn configuration of ocelot, and registered on each
- switch port through DSA port setup.
- Signed-off-by: Xiaoliang Yang <[email protected]>
- ---
- drivers/net/dsa/ocelot/Kconfig | 8 +
- drivers/net/dsa/ocelot/Makefile | 2 +
- drivers/net/dsa/ocelot/felix.c | 50 ++++
- drivers/net/dsa/ocelot/felix_tsn.c | 432 +++++++++++++++++++++++++++++++++
- drivers/net/dsa/ocelot/felix_tsn.h | 61 +++++
- drivers/net/dsa/ocelot/felix_vsc9959.c | 8 +-
- include/net/dsa.h | 1 +
- net/dsa/dsa2.c | 4 +
- 8 files changed, 564 insertions(+), 2 deletions(-)
- create mode 100644 drivers/net/dsa/ocelot/felix_tsn.c
- create mode 100644 drivers/net/dsa/ocelot/felix_tsn.h
- --- a/drivers/net/dsa/ocelot/Kconfig
- +++ b/drivers/net/dsa/ocelot/Kconfig
- @@ -9,3 +9,11 @@ config NET_DSA_MSCC_FELIX
- the Vitesse / Microsemi / Microchip Ocelot family of switching cores.
- It is embedded as a PCIe function of the NXP LS1028A ENETC integrated
- endpoint.
- +
- +config MSCC_FELIX_SWITCH_TSN
- + tristate "TSN on FELIX switch driver"
- + depends on NET_DSA_MSCC_FELIX
- + depends on TSN
- + help
- + This driver supports TSN on felix switch.
- +
- --- a/drivers/net/dsa/ocelot/Makefile
- +++ b/drivers/net/dsa/ocelot/Makefile
- @@ -4,3 +4,5 @@ obj-$(CONFIG_NET_DSA_MSCC_FELIX) += mscc
- mscc_felix-objs := \
- felix.o \
- felix_vsc9959.o
- +
- +obj-$(CONFIG_MSCC_FELIX_SWITCH_TSN) += felix_tsn.o
- --- a/drivers/net/dsa/ocelot/felix.c
- +++ b/drivers/net/dsa/ocelot/felix.c
- @@ -9,6 +9,38 @@
- #include <linux/of.h>
- #include <net/dsa.h>
- #include "felix.h"
- +#include "felix_tsn.h"
- +
- +#ifdef CONFIG_MSCC_FELIX_SWITCH_TSN
- +const struct tsn_ops switch_tsn_ops = {
- + .device_init = felix_tsn_init,
- + .get_capability = felix_tsn_get_cap,
- + .qbv_set = felix_qbv_set,
- + .qbv_get = felix_qbv_get,
- + .qbv_get_status = felix_qbv_get_status,
- + .qbu_set = felix_qbu_set,
- + .qbu_get = felix_qbu_get,
- + .cb_streamid_set = felix_cb_streamid_set,
- + .cb_streamid_get = felix_cb_streamid_get,
- + .cb_streamid_counters_get = felix_cb_streamid_counters_get,
- + .qci_sfi_set = felix_qci_sfi_set,
- + .qci_sfi_get = felix_qci_sfi_get,
- + .qci_sfi_counters_get = felix_qci_sfi_counters_get,
- + .qci_get_maxcap = felix_qci_max_cap_get,
- + .qci_sgi_set = felix_qci_sgi_set,
- + .qci_sgi_get = felix_qci_sgi_get,
- + .qci_sgi_status_get = felix_qci_sgi_status_get,
- + .qci_fmi_set = felix_qci_fmi_set,
- + .qci_fmi_get = felix_qci_fmi_get,
- + .cbs_set = felix_cbs_set,
- + .cbs_get = felix_cbs_get,
- + .ct_set = felix_cut_thru_set,
- + .cbgen_set = felix_seq_gen_set,
- + .cbrec_set = felix_seq_rec_set,
- + .cb_get = felix_cb_get,
- + .dscp_set = felix_dscp_set,
- +};
- +#endif
-
- static enum dsa_tag_protocol felix_get_tag_protocol(struct dsa_switch *ds,
- int port)
- @@ -138,6 +170,21 @@ static int felix_vlan_del(struct dsa_swi
- return 0;
- }
-
- +#ifdef CONFIG_MSCC_FELIX_SWITCH_TSN
- +static int felix_tsn_enable(struct dsa_port *dp)
- +{
- + struct net_device *dev;
- +
- + if (dp->type == DSA_PORT_TYPE_USER) {
- + dev = dp->slave;
- + tsn_port_register(dev,
- + (struct tsn_ops *)&switch_tsn_ops,
- + GROUP_OFFSET_SWITCH);
- + }
- + return 0;
- +}
- +#endif
- +
- static int felix_port_enable(struct dsa_switch *ds, int port,
- struct phy_device *phy)
- {
- @@ -386,6 +433,9 @@ static const struct dsa_switch_ops felix
- .port_hwtstamp_set = felix_hwtstamp_set,
- .port_rxtstamp = felix_rxtstamp,
- .port_txtstamp = felix_txtstamp,
- +#ifdef CONFIG_MSCC_FELIX_SWITCH_TSN
- + .port_tsn_enable = felix_tsn_enable,
- +#endif
- };
-
- static struct felix_info *felix_instance_tbl[] = {
- --- /dev/null
- +++ b/drivers/net/dsa/ocelot/felix_tsn.c
- @@ -0,0 +1,432 @@
- +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
- +/* Felix Switch TSN driver
- + *
- + * Copyright 2018-2019 NXP
- + */
- +
- +#include <linux/io.h>
- +#include <linux/module.h>
- +#include <linux/kernel.h>
- +#include <linux/pci.h>
- +#include <soc/mscc/ocelot.h>
- +#include <net/tsn.h>
- +#include "felix.h"
- +
- +static struct ocelot *felix_dev_to_ocelot(struct net_device *ndev)
- +{
- + struct pci_dev *pdev;
- + struct felix *felix;
- +
- + pdev = list_entry(ndev->dev.parent, struct pci_dev, dev);
- + felix = pci_get_drvdata(pdev);
- + if (!felix)
- + return NULL;
- +
- + return &felix->ocelot;
- +}
- +
- +static int felix_dev_to_port(struct net_device *ndev, struct ocelot *ocelot)
- +{
- + struct felix *felix = ocelot_to_felix(ocelot);
- + struct dsa_switch *ds = felix->ds;
- + struct dsa_port *dp;
- + int i;
- +
- + for (i = 0; i < ds->num_ports; i++) {
- + dp = &ds->ports[i];
- + if (dp->dn == ndev->dev.of_node)
- + return dp->index;
- + }
- +
- + return -ENODEV;
- +}
- +
- +u32 felix_tsn_get_cap(struct net_device *ndev)
- +{
- + u32 cap = 0;
- +
- + cap = (TSN_CAP_QBV | TSN_CAP_QCI | TSN_CAP_QBU | TSN_CAP_CBS |
- + TSN_CAP_CB | TSN_CAP_TBS | TSN_CAP_CTH);
- +
- + return cap;
- +}
- +
- +int felix_qbv_set(struct net_device *ndev,
- + struct tsn_qbv_conf *shaper_config)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qbv_set(ocelot, port, shaper_config);
- +}
- +
- +int felix_qbv_get(struct net_device *ndev,
- + struct tsn_qbv_conf *shaper_config)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qbv_get(ocelot, port, shaper_config);
- +}
- +
- +int felix_qbv_get_status(struct net_device *ndev,
- + struct tsn_qbv_status *qbvstatus)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qbv_get_status(ocelot, port, qbvstatus);
- +}
- +
- +int felix_qbu_set(struct net_device *ndev, u8 preemptible)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qbu_set(ocelot, port, preemptible);
- +}
- +
- +int felix_qbu_get(struct net_device *ndev, struct tsn_preempt_status *c)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qbu_get(ocelot, port, c);
- +}
- +
- +int felix_cb_streamid_set(struct net_device *ndev, u32 index, bool enable,
- + struct tsn_cb_streamid *streamid)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_cb_streamid_set(ocelot, port, index, enable, streamid);
- +}
- +
- +int felix_cb_streamid_get(struct net_device *ndev, u32 index,
- + struct tsn_cb_streamid *streamid)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_cb_streamid_get(ocelot, port, index, streamid);
- +}
- +
- +int felix_cb_streamid_counters_get(struct net_device *ndev, u32 index,
- + struct tsn_cb_streamid_counters *sc)
- +{
- + return 0;
- +}
- +
- +int felix_qci_sfi_set(struct net_device *ndev, u32 index, bool enable,
- + struct tsn_qci_psfp_sfi_conf *sfi)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qci_sfi_set(ocelot, port, index, enable, sfi);
- +}
- +
- +int felix_qci_sfi_get(struct net_device *ndev, u32 index,
- + struct tsn_qci_psfp_sfi_conf *sfi)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qci_sfi_get(ocelot, port, index, sfi);
- +}
- +
- +int felix_qci_sfi_counters_get(struct net_device *ndev, u32 index,
- + struct tsn_qci_psfp_sfi_counters *sfi_cnt)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qci_sfi_counters_get(ocelot, port, index, sfi_cnt);
- +}
- +
- +int felix_qci_max_cap_get(struct net_device *ndev,
- + struct tsn_qci_psfp_stream_param *stream_para)
- +{
- + struct ocelot *ocelot;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- +
- + return ocelot_qci_max_cap_get(ocelot, stream_para);
- +}
- +
- +int felix_qci_sgi_set(struct net_device *ndev, u32 index,
- + struct tsn_qci_psfp_sgi_conf *sgi_conf)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qci_sgi_set(ocelot, port, index, sgi_conf);
- +}
- +
- +int felix_qci_sgi_get(struct net_device *ndev, u32 index,
- + struct tsn_qci_psfp_sgi_conf *sgi_conf)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qci_sgi_get(ocelot, port, index, sgi_conf);
- +}
- +
- +int felix_qci_sgi_status_get(struct net_device *ndev, u32 index,
- + struct tsn_psfp_sgi_status *sgi_status)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qci_sgi_status_get(ocelot, port, index, sgi_status);
- +}
- +
- +int felix_qci_fmi_set(struct net_device *ndev, u32 index,
- + bool enable, struct tsn_qci_psfp_fmi *fmi)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qci_fmi_set(ocelot, port, index, enable, fmi);
- +}
- +
- +int felix_qci_fmi_get(struct net_device *ndev, u32 index,
- + struct tsn_qci_psfp_fmi *fmi,
- + struct tsn_qci_psfp_fmi_counters *counters)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_qci_fmi_get(ocelot, port, index, fmi, counters);
- +}
- +
- +int felix_cbs_set(struct net_device *ndev, u8 tc, u8 bw)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_cbs_set(ocelot, port, tc, bw);
- +}
- +
- +int felix_cbs_get(struct net_device *ndev, u8 tc)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_cbs_get(ocelot, port, tc);
- +}
- +
- +int felix_cut_thru_set(struct net_device *ndev, u8 cut_thru)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_cut_thru_set(ocelot, port, cut_thru);
- +}
- +
- +int felix_seq_gen_set(struct net_device *ndev, u32 index,
- + struct tsn_seq_gen_conf *sg_conf)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_seq_gen_set(ocelot, port, index, sg_conf);
- +}
- +
- +int felix_seq_rec_set(struct net_device *ndev, u32 index,
- + struct tsn_seq_rec_conf *sr_conf)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_seq_rec_set(ocelot, port, index, sr_conf);
- +}
- +
- +int felix_cb_get(struct net_device *ndev, u32 index,
- + struct tsn_cb_status *c)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_cb_get(ocelot, port, index, c);
- +}
- +
- +int felix_dscp_set(struct net_device *ndev, bool enable, const u8 dscp_ix,
- + struct tsn_qos_switch_dscp_conf *c)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return -ENODEV;
- + port = felix_dev_to_port(ndev, ocelot);
- + if (port < 0)
- + return -ENODEV;
- +
- + return ocelot_dscp_set(ocelot, port, enable, dscp_ix, c);
- +}
- +
- +void felix_tsn_init(struct net_device *ndev)
- +{
- + struct ocelot *ocelot;
- + int port;
- +
- + ocelot = felix_dev_to_ocelot(ndev);
- + if (!ocelot)
- + return;
- + port = felix_dev_to_port(ndev, ocelot);
- +
- + ocelot_pcp_map_enable(ocelot, port);
- + ocelot_rtag_parse_enable(ocelot, port);
- +}
- --- /dev/null
- +++ b/drivers/net/dsa/ocelot/felix_tsn.h
- @@ -0,0 +1,61 @@
- +/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
- + *
- + * TSN_SWITCH driver
- + *
- + * Copyright 2018-2019 NXP
- + */
- +
- +#ifndef _MSCC_FELIX_SWITCH_TSN_H_
- +#define _MSCC_FELIX_SWITCH_TSN_H_
- +#include <net/tsn.h>
- +
- +u32 felix_tsn_get_cap(struct net_device *ndev);
- +int felix_qbv_set(struct net_device *ndev,
- + struct tsn_qbv_conf *shaper_config);
- +int felix_qbv_get(struct net_device *ndev,
- + struct tsn_qbv_conf *shaper_config);
- +int felix_qbv_get_status(struct net_device *ndev,
- + struct tsn_qbv_status *qbvstatus);
- +int felix_cut_thru_set(struct net_device *ndev, u8 cut_thru);
- +int felix_cbs_set(struct net_device *ndev, u8 tc, u8 bw);
- +int felix_cbs_get(struct net_device *ndev, u8 tc);
- +int felix_qbu_set(struct net_device *ndev, u8 preemptible);
- +int felix_qbu_get(struct net_device *ndev, struct tsn_preempt_status *c);
- +int felix_cb_streamid_get(struct net_device *ndev, u32 index,
- + struct tsn_cb_streamid *streamid);
- +int felix_cb_streamid_set(struct net_device *ndev, u32 index,
- + bool enable, struct tsn_cb_streamid *streamid);
- +int felix_cb_streamid_counters_get(struct net_device *ndev, u32 index,
- + struct tsn_cb_streamid_counters *sc);
- +int felix_qci_sfi_get(struct net_device *ndev, u32 index,
- + struct tsn_qci_psfp_sfi_conf *sfi);
- +int felix_qci_sfi_set(struct net_device *ndev, u32 index,
- + bool enable, struct tsn_qci_psfp_sfi_conf *sfi);
- +int felix_cb_streamid_counters_get(struct net_device *ndev, u32 index,
- + struct tsn_cb_streamid_counters *s_counters);
- +int felix_qci_sfi_counters_get(struct net_device *ndev, u32 index,
- + struct tsn_qci_psfp_sfi_counters *sfi_counters);
- +int felix_qci_max_cap_get(struct net_device *ndev,
- + struct tsn_qci_psfp_stream_param *stream_para);
- +int felix_qci_sgi_set(struct net_device *ndev, u32 index,
- + struct tsn_qci_psfp_sgi_conf *sgi_conf);
- +int felix_qci_sgi_get(struct net_device *ndev, u32 index,
- + struct tsn_qci_psfp_sgi_conf *sgi_conf);
- +int felix_qci_sgi_status_get(struct net_device *ndev, u16 index,
- + struct tsn_psfp_sgi_status *sgi_status);
- +int felix_qci_fmi_set(struct net_device *ndev, u32 index,
- + bool enable, struct tsn_qci_psfp_fmi *fmi);
- +int felix_qci_fmi_get(struct net_device *ndev, u32 index,
- + struct tsn_qci_psfp_fmi *fmi,
- + struct tsn_qci_psfp_fmi_counters *counters);
- +int felix_seq_gen_set(struct net_device *ndev, u32 index,
- + struct tsn_seq_gen_conf *sg_conf);
- +int felix_seq_rec_set(struct net_device *ndev, u32 index,
- + struct tsn_seq_rec_conf *sr_conf);
- +int felix_cb_get(struct net_device *ndev, u32 index,
- + struct tsn_cb_status *c);
- +int felix_dscp_set(struct net_device *ndev, bool enable, const u8 dscp_ix,
- + struct tsn_qos_switch_dscp_conf *c);
- +
- +void felix_tsn_init(struct net_device *ndev);
- +#endif
- --- a/drivers/net/dsa/ocelot/felix_vsc9959.c
- +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
- @@ -176,7 +176,7 @@ static const u32 vsc9959_qsys_regmap[] =
- REG(QSYS_QMAXSDU_CFG_6, 0x00f62c),
- REG(QSYS_QMAXSDU_CFG_7, 0x00f648),
- REG(QSYS_PREEMPTION_CFG, 0x00f664),
- - REG_RESERVED(QSYS_CIR_CFG),
- + REG(QSYS_CIR_CFG, 0x000000),
- REG(QSYS_EIR_CFG, 0x000004),
- REG(QSYS_SE_CFG, 0x000008),
- REG(QSYS_SE_DWRR_CFG, 0x00000c),
- @@ -269,7 +269,7 @@ static const u32 vsc9959_sys_regmap[] =
- REG_RESERVED(SYS_MMGT_FAST),
- REG_RESERVED(SYS_EVENTS_DIF),
- REG_RESERVED(SYS_EVENTS_CORE),
- - REG_RESERVED(SYS_CNT),
- + REG(SYS_CNT, 0x000000),
- REG(SYS_PTP_STATUS, 0x000f14),
- REG(SYS_PTP_TXSTAMP, 0x000f18),
- REG(SYS_PTP_NXT, 0x000f1c),
- @@ -290,6 +290,10 @@ static const u32 vsc9959_ptp_regmap[] =
- REG(PTP_CFG_MISC, 0x0000a0),
- REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4),
- REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8),
- + REG(PTP_CUR_NSF, 0x0000bc),
- + REG(PTP_CUR_NSEC, 0x0000c0),
- + REG(PTP_CUR_SEC_LSB, 0x0000c4),
- + REG(PTP_CUR_SEC_MSB, 0x0000c8),
- };
-
- static const u32 vsc9959_gcb_regmap[] = {
- --- a/include/net/dsa.h
- +++ b/include/net/dsa.h
- @@ -552,6 +552,7 @@ struct dsa_switch_ops {
- */
- netdev_tx_t (*port_deferred_xmit)(struct dsa_switch *ds, int port,
- struct sk_buff *skb);
- + int (*port_tsn_enable)(struct dsa_port *dp);
- };
-
- struct dsa_switch_driver {
- --- a/net/dsa/dsa2.c
- +++ b/net/dsa/dsa2.c
- @@ -323,6 +323,10 @@ static int dsa_port_setup(struct dsa_por
- if (err)
- break;
-
- + /* Enable TSN function on switch port */
- + if (ds->ops->port_tsn_enable)
- + ds->ops->port_tsn_enable(dp);
- +
- devlink_port_type_eth_set(dlp, dp->slave);
- break;
- }
|