Commit 27bcd122 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'icssg-driver'



MD Danish Anwar says:

====================
Introduce ICSSG based ethernet Driver

The Programmable Real-time Unit and Industrial Communication Subsystem
Gigabit (PRU_ICSSG) is a low-latency microcontroller subsystem in the TI
SoCs. This subsystem is provided for the use cases like the implementation
of custom peripheral interfaces, offloading of tasks from the other
processor cores of the SoC, etc.

The subsystem includes many accelerators for data processing like
multiplier and multiplier-accumulator. It also has peripherals like
UART, MII/RGMII, MDIO, etc. Every ICSSG core includes two 32-bit
load/store RISC CPU cores called PRUs.

The above features allow it to be used for implementing custom firmware
based peripherals like ethernet.

This series adds the YAML documentation and the driver with basic EMAC
support for TI AM654 Silicon Rev 2 SoC with the PRU_ICSSG Sub-system.
running dual-EMAC firmware.
This currently supports basic EMAC with 1Gbps and 100Mbps link. 10M and
half-duplex modes are not yet supported because they require the support
of an IEP, which will be added later.
Advanced features like switch-dev and timestamping will be added later.

This is the v13 of the patch series [v1]. This version of the patchset
addresses comments made on v12.

There series doesn't have any dependency.

Changes from v12 to v13 :
*) Rebased the series on latest net-next.
*) Addressed Jakub's comments on ndo_xmit API. Now we will only stop queues
   based on occupancy not on dma errors.
*) Removed limiting the number of serviced packets to budget for Tx NAPI.
   Now Tx NAPI will keep servicing packets.
*) Removed netif_running() check when packet arrives.
*) Introduced prototypes of APIs in the same patch where these APIs are added.
   Dropped __maybe_unused tags as compiler only cares about prototypes
   existing, not whether actual callers are in place. Now prototypes of these
   APIs are present in the same patch where they are introduced but thes APIs
   are called later (in patch 6).

Changes from v11 to v12 :
*) Rebased the series on latest net-next.
*) Addressed Jakub's comments on ndo_xmit API.
*) Added hooks to .get_rmon_stats for the driver. Now tx / rx bucket size
   and frame counts per bucket will be fetched by ethtool_rmon_stats instead
   of ethtool -S.
*) Added __maybe_unused tags to unused config and classifier APIs in patch
   2,3 and 4. These tags are later removed in patch 6.

Changes from v10 to v11 :
*) Rebased the series on latest net-next.
*) Split the ICSSG driver introduction patch into 9 different patches as
   asked by Jakub.
*) Introduced new patch(patch 8/10) to dump Standard network interface
   staticstics via ndo_get_stats64. Now certain stats that are reported by
   ICSSG hardware and are also part of struct rtnl_link_stats64, will be
   reported by ndo_get_stats64. While other stats that are not part of the
   struct rtnl_link_stats64 will be reported by ethtool -S. These stats
   are not duplicated.

Changes from v9 to v10 :
*) Rebased the series on latest net-next.
*) Moved 'ndev prueth->emac[mac] == emac' assignment to the end of function
   prueth_netdev_init().
*) In unsupported phy_mode switch case instead of returning -EINVAL, store
   the error code in ret and 'goto free'

Changes from v8 to v9 :
*) Rebased the series on latest net-next.
*) Fixed smatch and sparse warnings as pointed by Simon.
*) Fixed leaky ndev in prueth_netdev_init() as asked by Simon.

Changes from v7 to v8 :
*) Rebased the series on 6.5-rc1.
*) Fixed few formattings.

Changes from v6 to v7 :
*) Added RB tag of Rob in patch 1 of this series.
*) Addressed Simon's comment on patch 2 of the series.
*) Rebased patchset on next-20230428 linux-next.

Changes from v5 to v6 :
*) Added RB tag of Andrew Lunn in patch 2 of this series.
*) Addressed Rob's comment on patch 1 of the series.
*) Rebased patchset on next-20230421 linux-next.

Changes from v4 to v5 :
*) Re-arranged properties section in ti,icssg-prueth.yaml file.
*) Added requirement for minimum one ethernet port.
*) Fixed some minor formatting errors as asked by Krzysztof.
*) Dropped SGMII mode from enum mii_mode as SGMII mode is not currently
   supported by the driver.
*) Added switch-case block to handle different phy modes by ICSSG driver.

Changes from v3 to v4 :
*) Addressed Krzysztof's comments and fixed dt_binding_check errors in
   patch 1/2.
*) Added interrupt-extended property in ethernet-ports properties section.
*) Fixed comments in file icssg_switch_map.h according to the Linux coding
   style in patch 2/2. Added Documentation of structures in patch 2/2.

Changes from v2 to v3 :
*) Addressed Rob and Krzysztof's comments on patch 1 of this series.
   Fixed indentation. Removed description and pinctrl section from
   ti,icssg-prueth.yaml file.
*) Addressed Krzysztof, Paolo, Randy, Andrew and Christophe's comments on
   patch 2 of this seires.
*) Fixed blanklines in Kconfig and Makefile. Changed structures to const
   as suggested by Krzysztof.
*) Fixed while loop logic in emac_tx_complete_packets() API as suggested
   by Paolo. Previously in the loop's last iteration 'budget' was 0 and
   napi_consume_skb would wrongly assume the caller is not in NAPI context
   Now, budget won't be zero in last iteration of loop.
*) Removed inline functions addr_to_da1() and addr_to_da0() as asked by
   Andrew.
*) Added dev_err_probe() instead of dev_err() as suggested by Christophe.
*) In ti,icssg-prueth.yaml file, in the patternProperties section of
   ethernet-ports, kept the port name as "port" instead of "ethernet-port"
   as all other drivers were using "port". Will change it if is compulsory
   to use "ethernet-port".
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 745d7e38 a46750a1
Loading
Loading
Loading
Loading
+184 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/ti,icssg-prueth.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Texas Instruments ICSSG PRUSS Ethernet

maintainers:
  - Md Danish Anwar <danishanwar@ti.com>

description:
  Ethernet based on the Programmable Real-Time Unit and Industrial
  Communication Subsystem.

allOf:
  - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#

properties:
  compatible:
    enum:
      - ti,am654-icssg-prueth  # for AM65x SoC family

  sram:
    $ref: /schemas/types.yaml#/definitions/phandle
    description:
      phandle to MSMC SRAM node

  dmas:
    maxItems: 10

  dma-names:
    items:
      - const: tx0-0
      - const: tx0-1
      - const: tx0-2
      - const: tx0-3
      - const: tx1-0
      - const: tx1-1
      - const: tx1-2
      - const: tx1-3
      - const: rx0
      - const: rx1

  ti,mii-g-rt:
    $ref: /schemas/types.yaml#/definitions/phandle
    description:
      phandle to MII_G_RT module's syscon regmap.

  ti,mii-rt:
    $ref: /schemas/types.yaml#/definitions/phandle
    description:
      phandle to MII_RT module's syscon regmap

  interrupts:
    maxItems: 2
    description:
      Interrupt specifiers to TX timestamp IRQ.

  interrupt-names:
    items:
      - const: tx_ts0
      - const: tx_ts1

  ethernet-ports:
    type: object
    additionalProperties: false

    properties:
      '#address-cells':
        const: 1
      '#size-cells':
        const: 0

    patternProperties:
      ^port@[0-1]$:
        type: object
        description: ICSSG PRUETH external ports
        $ref: ethernet-controller.yaml#
        unevaluatedProperties: false

        properties:
          reg:
            items:
              - enum: [0, 1]
            description: ICSSG PRUETH port number

          interrupts:
            maxItems: 1

          ti,syscon-rgmii-delay:
            items:
              - items:
                  - description: phandle to system controller node
                  - description: The offset to ICSSG control register
            $ref: /schemas/types.yaml#/definitions/phandle-array
            description:
              phandle to system controller node and register offset
              to ICSSG control register for RGMII transmit delay

        required:
          - reg
    anyOf:
      - required:
          - port@0
      - required:
          - port@1

required:
  - compatible
  - sram
  - dmas
  - dma-names
  - ethernet-ports
  - ti,mii-g-rt
  - interrupts
  - interrupt-names

unevaluatedProperties: false

examples:
  - |
    /* Example k3-am654 base board SR2.0, dual-emac */
    pruss2_eth: ethernet {
        compatible = "ti,am654-icssg-prueth";
        pinctrl-names = "default";
        pinctrl-0 = <&icssg2_rgmii_pins_default>;
        sram = <&msmc_ram>;

        ti,prus = <&pru2_0>, <&rtu2_0>, <&tx_pru2_0>,
                  <&pru2_1>, <&rtu2_1>, <&tx_pru2_1>;
        firmware-name = "ti-pruss/am65x-pru0-prueth-fw.elf",
                        "ti-pruss/am65x-rtu0-prueth-fw.elf",
                        "ti-pruss/am65x-txpru0-prueth-fw.elf",
                        "ti-pruss/am65x-pru1-prueth-fw.elf",
                        "ti-pruss/am65x-rtu1-prueth-fw.elf",
                        "ti-pruss/am65x-txpru1-prueth-fw.elf";
        ti,pruss-gp-mux-sel = <2>,      /* MII mode */
                              <2>,
                              <2>,
                              <2>,      /* MII mode */
                              <2>,
                              <2>;
        dmas = <&main_udmap 0xc300>, /* egress slice 0 */
               <&main_udmap 0xc301>, /* egress slice 0 */
               <&main_udmap 0xc302>, /* egress slice 0 */
               <&main_udmap 0xc303>, /* egress slice 0 */
               <&main_udmap 0xc304>, /* egress slice 1 */
               <&main_udmap 0xc305>, /* egress slice 1 */
               <&main_udmap 0xc306>, /* egress slice 1 */
               <&main_udmap 0xc307>, /* egress slice 1 */
               <&main_udmap 0x4300>, /* ingress slice 0 */
               <&main_udmap 0x4301>; /* ingress slice 1 */
        dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
                    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
                    "rx0", "rx1";
        ti,mii-g-rt = <&icssg2_mii_g_rt>;
        interrupt-parent = <&icssg2_intc>;
        interrupts = <24 0 2>, <25 1 3>;
        interrupt-names = "tx_ts0", "tx_ts1";
        ethernet-ports {
            #address-cells = <1>;
            #size-cells = <0>;
            pruss2_emac0: port@0 {
                reg = <0>;
                phy-handle = <&pruss2_eth0_phy>;
                phy-mode = "rgmii-id";
                interrupts-extended = <&icssg2_intc 24>;
                ti,syscon-rgmii-delay = <&scm_conf 0x4120>;
                /* Filled in by bootloader */
                local-mac-address = [00 00 00 00 00 00];
            };

            pruss2_emac1: port@1 {
                reg = <1>;
                phy-handle = <&pruss2_eth1_phy>;
                phy-mode = "rgmii-id";
                interrupts-extended = <&icssg2_intc 25>;
                ti,syscon-rgmii-delay = <&scm_conf 0x4124>;
                /* Filled in by bootloader */
                local-mac-address = [00 00 00 00 00 00];
            };
        };
    };
+13 −0
Original line number Diff line number Diff line
@@ -183,4 +183,17 @@ config CPMAC
	help
	  TI AR7 CPMAC Ethernet support

config TI_ICSSG_PRUETH
	tristate "TI Gigabit PRU Ethernet driver"
	select PHYLIB
	depends on PRU_REMOTEPROC
	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
	help
	  Support dual Gigabit Ethernet ports over the ICSSG PRU Subsystem.
	  This subsystem is available starting with the AM65 platform.

	  This driver requires firmware binaries which will run on the PRUs
	  to support the Ethernet operation. Currently, it supports Ethernet
	  with 1G and 100M link speed.

endif # NET_VENDOR_TI
+10 −0
Original line number Diff line number Diff line
@@ -28,3 +28,13 @@ obj-$(CONFIG_TI_K3_AM65_CPSW_NUSS) += ti-am65-cpsw-nuss.o
ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o k3-cppi-desc-pool.o am65-cpsw-qos.o
ti-am65-cpsw-nuss-$(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV) += am65-cpsw-switchdev.o
obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o

obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg-prueth.o
icssg-prueth-y := k3-cppi-desc-pool.o \
		  icssg/icssg_prueth.o \
		  icssg/icssg_classifier.o \
		  icssg/icssg_queues.o \
		  icssg/icssg_config.o \
		  icssg/icssg_mii_cfg.o \
		  icssg/icssg_stats.o \
		  icssg/icssg_ethtool.o
+367 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* Texas Instruments ICSSG Ethernet Driver
 *
 * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
 *
 */

#include <linux/etherdevice.h>
#include <linux/types.h>
#include <linux/regmap.h>

#include "icssg_prueth.h"

#define ICSSG_NUM_CLASSIFIERS	16
#define ICSSG_NUM_FT1_SLOTS	8
#define ICSSG_NUM_FT3_SLOTS	16

#define ICSSG_NUM_CLASSIFIERS_IN_USE	5

/* Filter 1 - FT1 */
#define FT1_NUM_SLOTS	8
#define FT1_SLOT_SIZE	0x10	/* bytes */

/* offsets from FT1 slot base i.e. slot 1 start */
#define FT1_DA0		0x0
#define FT1_DA1		0x4
#define FT1_DA0_MASK	0x8
#define FT1_DA1_MASK	0xc

#define FT1_N_REG(slize, n, reg)	\
	(offs[slice].ft1_slot_base + FT1_SLOT_SIZE * (n) + (reg))

#define FT1_LEN_MASK		GENMASK(19, 16)
#define FT1_LEN_SHIFT		16
#define FT1_LEN(len)		(((len) << FT1_LEN_SHIFT) & FT1_LEN_MASK)
#define FT1_START_MASK		GENMASK(14, 0)
#define FT1_START(start)	((start) & FT1_START_MASK)
#define FT1_MATCH_SLOT(n)	(GENMASK(23, 16) & (BIT(n) << 16))

/* FT1 config type */
enum ft1_cfg_type {
	FT1_CFG_TYPE_DISABLED = 0,
	FT1_CFG_TYPE_EQ,
	FT1_CFG_TYPE_GT,
	FT1_CFG_TYPE_LT,
};

#define FT1_CFG_SHIFT(n)	(2 * (n))
#define FT1_CFG_MASK(n)		(0x3 << FT1_CFG_SHIFT((n)))

/* Filter 3 -  FT3 */
#define FT3_NUM_SLOTS	16
#define FT3_SLOT_SIZE	0x20	/* bytes */

/* offsets from FT3 slot n's base */
#define FT3_START		0
#define FT3_START_AUTO		0x4
#define FT3_START_OFFSET	0x8
#define FT3_JUMP_OFFSET		0xc
#define FT3_LEN			0x10
#define FT3_CFG			0x14
#define FT3_T			0x18
#define FT3_T_MASK		0x1c

#define FT3_N_REG(slize, n, reg)	\
	(offs[slice].ft3_slot_base + FT3_SLOT_SIZE * (n) + (reg))

/* offsets from rx_class n's base */
#define RX_CLASS_AND_EN		0
#define RX_CLASS_OR_EN		0x4
#define RX_CLASS_NUM_SLOTS	16
#define RX_CLASS_EN_SIZE	0x8	/* bytes */

#define RX_CLASS_N_REG(slice, n, reg)	\
	(offs[slice].rx_class_base + RX_CLASS_EN_SIZE * (n) + (reg))

/* RX Class Gates */
#define RX_CLASS_GATES_SIZE	0x4	/* bytes */

#define RX_CLASS_GATES_N_REG(slice, n)	\
	(offs[slice].rx_class_gates_base + RX_CLASS_GATES_SIZE * (n))

#define RX_CLASS_GATES_ALLOW_MASK	BIT(6)
#define RX_CLASS_GATES_RAW_MASK		BIT(5)
#define RX_CLASS_GATES_PHASE_MASK	BIT(4)

/* RX Class traffic data matching bits */
#define RX_CLASS_FT_UC				BIT(31)
#define RX_CLASS_FT_MC			BIT(30)
#define RX_CLASS_FT_BC			BIT(29)
#define RX_CLASS_FT_FW			BIT(28)
#define RX_CLASS_FT_RCV			BIT(27)
#define RX_CLASS_FT_VLAN		BIT(26)
#define RX_CLASS_FT_DA_P		BIT(25)
#define RX_CLASS_FT_DA_I		BIT(24)
#define RX_CLASS_FT_FT1_MATCH_MASK	GENMASK(23, 16)
#define RX_CLASS_FT_FT1_MATCH_SHIFT	16
#define RX_CLASS_FT_FT3_MATCH_MASK	GENMASK(15, 0)
#define RX_CLASS_FT_FT3_MATCH_SHIFT	0

#define RX_CLASS_FT_FT1_MATCH(slot)	\
	((BIT(slot) << RX_CLASS_FT_FT1_MATCH_SHIFT) & \
	RX_CLASS_FT_FT1_MATCH_MASK)

/* RX class type */
enum rx_class_sel_type {
	RX_CLASS_SEL_TYPE_OR = 0,
	RX_CLASS_SEL_TYPE_AND = 1,
	RX_CLASS_SEL_TYPE_OR_AND_AND = 2,
	RX_CLASS_SEL_TYPE_OR_OR_AND = 3,
};

#define FT1_CFG_SHIFT(n)	(2 * (n))
#define FT1_CFG_MASK(n)		(0x3 << FT1_CFG_SHIFT((n)))

#define RX_CLASS_SEL_SHIFT(n)	(2 * (n))
#define RX_CLASS_SEL_MASK(n)	(0x3 << RX_CLASS_SEL_SHIFT((n)))

#define ICSSG_CFG_OFFSET	0
#define MAC_INTERFACE_0		0x18
#define MAC_INTERFACE_1		0x1c

#define ICSSG_CFG_RX_L2_G_EN	BIT(2)

/* These are register offsets per PRU */
struct miig_rt_offsets {
	u32 mac0;
	u32 mac1;
	u32 ft1_start_len;
	u32 ft1_cfg;
	u32 ft1_slot_base;
	u32 ft3_slot_base;
	u32 ft3_p_base;
	u32 ft_rx_ptr;
	u32 rx_class_base;
	u32 rx_class_cfg1;
	u32 rx_class_cfg2;
	u32 rx_class_gates_base;
	u32 rx_green;
	u32 rx_rate_cfg_base;
	u32 rx_rate_src_sel0;
	u32 rx_rate_src_sel1;
	u32 tx_rate_cfg_base;
	u32 stat_base;
	u32 tx_hsr_tag;
	u32 tx_hsr_seq;
	u32 tx_vlan_type;
	u32 tx_vlan_ins;
};

/* These are the offset values for miig_rt_offsets registers */
static const struct miig_rt_offsets offs[] = {
	/* PRU0 */
	{
		0x8,
		0xc,
		0x80,
		0x84,
		0x88,
		0x108,
		0x308,
		0x408,
		0x40c,
		0x48c,
		0x490,
		0x494,
		0x4d4,
		0x4e4,
		0x504,
		0x508,
		0x50c,
		0x54c,
		0x63c,
		0x640,
		0x644,
		0x648,
	},
	/* PRU1 */
	{
		0x10,
		0x14,
		0x64c,
		0x650,
		0x654,
		0x6d4,
		0x8d4,
		0x9d4,
		0x9d8,
		0xa58,
		0xa5c,
		0xa60,
		0xaa0,
		0xab0,
		0xad0,
		0xad4,
		0xad8,
		0xb18,
		0xc08,
		0xc0c,
		0xc10,
		0xc14,
	},
};

static void rx_class_ft1_set_start_len(struct regmap *miig_rt, int slice,
				       u16 start, u8 len)
{
	u32 offset, val;

	offset = offs[slice].ft1_start_len;
	val = FT1_LEN(len) | FT1_START(start);
	regmap_write(miig_rt, offset, val);
}

static void rx_class_ft1_set_da(struct regmap *miig_rt, int slice,
				int n, const u8 *addr)
{
	u32 offset;

	offset = FT1_N_REG(slice, n, FT1_DA0);
	regmap_write(miig_rt, offset, (u32)(addr[0] | addr[1] << 8 |
		     addr[2] << 16 | addr[3] << 24));
	offset = FT1_N_REG(slice, n, FT1_DA1);
	regmap_write(miig_rt, offset, (u32)(addr[4] | addr[5] << 8));
}

static void rx_class_ft1_set_da_mask(struct regmap *miig_rt, int slice,
				     int n, const u8 *addr)
{
	u32 offset;

	offset = FT1_N_REG(slice, n, FT1_DA0_MASK);
	regmap_write(miig_rt, offset, (u32)(addr[0] | addr[1] << 8 |
		     addr[2] << 16 | addr[3] << 24));
	offset = FT1_N_REG(slice, n, FT1_DA1_MASK);
	regmap_write(miig_rt, offset, (u32)(addr[4] | addr[5] << 8));
}

static void rx_class_ft1_cfg_set_type(struct regmap *miig_rt, int slice, int n,
				      enum ft1_cfg_type type)
{
	u32 offset;

	offset = offs[slice].ft1_cfg;
	regmap_update_bits(miig_rt, offset, FT1_CFG_MASK(n),
			   type << FT1_CFG_SHIFT(n));
}

static void rx_class_sel_set_type(struct regmap *miig_rt, int slice, int n,
				  enum rx_class_sel_type type)
{
	u32 offset;

	offset = offs[slice].rx_class_cfg1;
	regmap_update_bits(miig_rt, offset, RX_CLASS_SEL_MASK(n),
			   type << RX_CLASS_SEL_SHIFT(n));
}

static void rx_class_set_and(struct regmap *miig_rt, int slice, int n,
			     u32 data)
{
	u32 offset;

	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_AND_EN);
	regmap_write(miig_rt, offset, data);
}

static void rx_class_set_or(struct regmap *miig_rt, int slice, int n,
			    u32 data)
{
	u32 offset;

	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN);
	regmap_write(miig_rt, offset, data);
}

void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac)
{
	regmap_write(miig_rt, MAC_INTERFACE_0, (u32)(mac[0] | mac[1] << 8 |
		     mac[2] << 16 | mac[3] << 24));
	regmap_write(miig_rt, MAC_INTERFACE_1, (u32)(mac[4] | mac[5] << 8));
}

void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac)
{
	regmap_write(miig_rt, offs[slice].mac0, (u32)(mac[0] | mac[1] << 8 |
		     mac[2] << 16 | mac[3] << 24));
	regmap_write(miig_rt, offs[slice].mac1, (u32)(mac[4] | mac[5] << 8));
}

/* disable all RX traffic */
void icssg_class_disable(struct regmap *miig_rt, int slice)
{
	u32 data, offset;
	int n;

	/* Enable RX_L2_G */
	regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_RX_L2_G_EN,
			   ICSSG_CFG_RX_L2_G_EN);

	for (n = 0; n < ICSSG_NUM_CLASSIFIERS; n++) {
		/* AND_EN = 0 */
		rx_class_set_and(miig_rt, slice, n, 0);
		/* OR_EN = 0 */
		rx_class_set_or(miig_rt, slice, n, 0);

		/* set CFG1 to OR */
		rx_class_sel_set_type(miig_rt, slice, n, RX_CLASS_SEL_TYPE_OR);

		/* configure gate */
		offset = RX_CLASS_GATES_N_REG(slice, n);
		regmap_read(miig_rt, offset, &data);
		/* clear class_raw so we go through filters */
		data &= ~RX_CLASS_GATES_RAW_MASK;
		/* set allow and phase mask */
		data |= RX_CLASS_GATES_ALLOW_MASK | RX_CLASS_GATES_PHASE_MASK;
		regmap_write(miig_rt, offset, data);
	}

	/* FT1 Disabled */
	for (n = 0; n < ICSSG_NUM_FT1_SLOTS; n++) {
		const u8 addr[] = { 0, 0, 0, 0, 0, 0, };

		rx_class_ft1_cfg_set_type(miig_rt, slice, n,
					  FT1_CFG_TYPE_DISABLED);
		rx_class_ft1_set_da(miig_rt, slice, n, addr);
		rx_class_ft1_set_da_mask(miig_rt, slice, n, addr);
	}

	/* clear CFG2 */
	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
}

void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti)
{
	u32 data;

	/* defaults */
	icssg_class_disable(miig_rt, slice);

	/* Setup Classifier */
	/* match on Broadcast or MAC_PRU address */
	data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P;

	/* multicast */
	if (allmulti)
		data |= RX_CLASS_FT_MC;

	rx_class_set_or(miig_rt, slice, 0, data);

	/* set CFG1 for OR_OR_AND for classifier */
	rx_class_sel_set_type(miig_rt, slice, 0, RX_CLASS_SEL_TYPE_OR_OR_AND);

	/* clear CFG2 */
	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
}

/* required for SAV check */
void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr)
{
	const u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, };

	rx_class_ft1_set_start_len(miig_rt, slice, 0, 6);
	rx_class_ft1_set_da(miig_rt, slice, 0, mac_addr);
	rx_class_ft1_set_da_mask(miig_rt, slice, 0, mask_addr);
	rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ);
}
+450 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading