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

Merge branch 'net-tsnep-multiqueue'



Gerhard Engleder says:

====================
tsnep: multi queue support and some other improvements

Add support for additional TX/RX queues along with RX flow classification
support.

Binding is extended to allow additional interrupts for additional TX/RX
queues. Also dma-coherent is allowed as minor improvement.

RX path optimisation is done by using page pool as preparations for future
XDP support.

v4:
- rework dma-coherent commit message (Krzysztof Kozlowski)
- fixed order of interrupt-names in binding (Krzysztof Kozlowski)
- add line break between examples in binding (Krzysztof Kozlowski)
- add RX_CLS_LOC_ANY support to RX flow classification

v3:
- now with changes in cover letter

v2:
- use netdev_name() (Jakub Kicinski)
- use ENOENT if RX flow rule is not found (Jakub Kicinski)
- eliminate return code of tsnep_add_rule() (Jakub Kicinski)
- remove commit with lazy refill due to depletion problem (Jakub Kicinski)
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d742ea6b bb837a37
Loading
Loading
Loading
Loading
+41 −2
Original line number Diff line number Diff line
@@ -20,7 +20,26 @@ properties:
    maxItems: 1

  interrupts:
    maxItems: 1
    minItems: 1
    maxItems: 8

  interrupt-names:
    minItems: 1
    items:
      - const: mac
      - const: txrx-1
      - const: txrx-2
      - const: txrx-3
      - const: txrx-4
      - const: txrx-5
      - const: txrx-6
      - const: txrx-7
    description:
      The main interrupt for basic MAC features and the first TX/RX queue pair
      is named "mac". "txrx-[1-7]" are the interrupts for additional TX/RX
      queue pairs.

  dma-coherent: true

  local-mac-address: true

@@ -58,7 +77,7 @@ examples:
    axi {
        #address-cells = <2>;
        #size-cells = <2>;
        tnsep0: ethernet@a0000000 {
        tsnep0: ethernet@a0000000 {
            compatible = "engleder,tsnep";
            reg = <0x0 0xa0000000 0x0 0x10000>;
            interrupts = <0 89 1>;
@@ -76,4 +95,24 @@ examples:
                };
            };
        };

        tsnep1: ethernet@a0010000 {
            compatible = "engleder,tsnep";
            reg = <0x0 0xa0010000 0x0 0x10000>;
            interrupts = <0 93 1>, <0 94 1>, <0 95 1>, <0 96 1>;
            interrupt-names = "mac", "txrx-1", "txrx-2", "txrx-3";
            interrupt-parent = <&gic>;
            local-mac-address = [00 00 00 00 00 00];
            phy-mode = "rgmii";
            phy-handle = <&phy1>;
            mdio {
                #address-cells = <1>;
                #size-cells = <0>;
                suppress-preamble;
                phy1: ethernet-phy@1 {
                    reg = <1>;
                    rxc-skew-ps = <1080>;
                };
            };
        };
    };
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ config TSNEP
	depends on HAS_IOMEM && HAS_DMA
	depends on PTP_1588_CLOCK_OPTIONAL
	select PHYLIB
	select PAGE_POOL
	help
	  Support for the Engleder TSN endpoint Ethernet MAC IP Core.

+1 −1
Original line number Diff line number Diff line
@@ -6,5 +6,5 @@
obj-$(CONFIG_TSNEP) += tsnep.o

tsnep-objs := tsnep_main.o tsnep_ethtool.o tsnep_ptp.o tsnep_tc.o \
	      $(tsnep-y)
	      tsnep_rxnfc.o $(tsnep-y)
tsnep-$(CONFIG_TSNEP_SELFTESTS) += tsnep_selftests.o
+42 −5
Original line number Diff line number Diff line
@@ -21,8 +21,6 @@
#define TSNEP_RING_ENTRIES_PER_PAGE (PAGE_SIZE / TSNEP_DESC_SIZE)
#define TSNEP_RING_PAGE_COUNT (TSNEP_RING_SIZE / TSNEP_RING_ENTRIES_PER_PAGE)

#define TSNEP_QUEUES 1

struct tsnep_gcl {
	void __iomem *addr;

@@ -39,6 +37,24 @@ struct tsnep_gcl {
	bool change;
};

enum tsnep_rxnfc_filter_type {
	TSNEP_RXNFC_ETHER_TYPE,
};

struct tsnep_rxnfc_filter {
	enum tsnep_rxnfc_filter_type type;
	union {
		u16 ether_type;
	};
};

struct tsnep_rxnfc_rule {
	struct list_head list;
	struct tsnep_rxnfc_filter filter;
	int queue_index;
	int location;
};

struct tsnep_tx_entry {
	struct tsnep_tx_desc *desc;
	struct tsnep_tx_desc_wb *desc_wb;
@@ -55,6 +71,7 @@ struct tsnep_tx_entry {
struct tsnep_tx {
	struct tsnep_adapter *adapter;
	void __iomem *addr;
	int queue_index;

	void *page[TSNEP_RING_PAGE_COUNT];
	dma_addr_t page_dma[TSNEP_RING_PAGE_COUNT];
@@ -79,9 +96,9 @@ struct tsnep_rx_entry {

	u32 properties;

	struct sk_buff *skb;
	struct page *page;
	size_t len;
	DEFINE_DMA_UNMAP_ADDR(dma);
	dma_addr_t dma;
};

struct tsnep_rx {
@@ -96,6 +113,7 @@ struct tsnep_rx {
	int read;
	u32 owner_counter;
	int increment_owner_counter;
	struct page_pool *page_pool;

	u32 packets;
	u32 bytes;
@@ -105,12 +123,14 @@ struct tsnep_rx {

struct tsnep_queue {
	struct tsnep_adapter *adapter;
	char name[IFNAMSIZ + 9];

	struct tsnep_tx *tx;
	struct tsnep_rx *rx;

	struct napi_struct napi;

	int irq;
	u32 irq_mask;
};

@@ -126,7 +146,6 @@ struct tsnep_adapter {
	struct platform_device *pdev;
	struct device *dmadev;
	void __iomem *addr;
	int irq;

	bool gate_control;
	/* gate control lock */
@@ -141,6 +160,12 @@ struct tsnep_adapter {
	/* ptp clock lock */
	spinlock_t ptp_lock;

	/* RX flow classification rules lock */
	struct mutex rxnfc_lock;
	struct list_head rxnfc_rules;
	int rxnfc_count;
	int rxnfc_max;

	int num_tx_queues;
	struct tsnep_tx tx[TSNEP_MAX_QUEUES];
	int num_rx_queues;
@@ -161,6 +186,18 @@ void tsnep_tc_cleanup(struct tsnep_adapter *adapter);
int tsnep_tc_setup(struct net_device *netdev, enum tc_setup_type type,
		   void *type_data);

int tsnep_rxnfc_init(struct tsnep_adapter *adapter);
void tsnep_rxnfc_cleanup(struct tsnep_adapter *adapter);
int tsnep_rxnfc_get_rule(struct tsnep_adapter *adapter,
			 struct ethtool_rxnfc *cmd);
int tsnep_rxnfc_get_all(struct tsnep_adapter *adapter,
			struct ethtool_rxnfc *cmd,
			u32 *rule_locs);
int tsnep_rxnfc_add_rule(struct tsnep_adapter *adapter,
			 struct ethtool_rxnfc *cmd);
int tsnep_rxnfc_del_rule(struct tsnep_adapter *adapter,
			 struct ethtool_rxnfc *cmd);

#if IS_ENABLED(CONFIG_TSNEP_SELFTESTS)
int tsnep_ethtool_get_test_count(void);
void tsnep_ethtool_get_test_strings(u8 *data);
+40 −0
Original line number Diff line number Diff line
@@ -250,6 +250,44 @@ static int tsnep_ethtool_get_sset_count(struct net_device *netdev, int sset)
	}
}

static int tsnep_ethtool_get_rxnfc(struct net_device *dev,
				   struct ethtool_rxnfc *cmd, u32 *rule_locs)
{
	struct tsnep_adapter *adapter = netdev_priv(dev);

	switch (cmd->cmd) {
	case ETHTOOL_GRXRINGS:
		cmd->data = adapter->num_rx_queues;
		return 0;
	case ETHTOOL_GRXCLSRLCNT:
		cmd->rule_cnt = adapter->rxnfc_count;
		cmd->data = adapter->rxnfc_max;
		cmd->data |= RX_CLS_LOC_SPECIAL;
		return 0;
	case ETHTOOL_GRXCLSRULE:
		return tsnep_rxnfc_get_rule(adapter, cmd);
	case ETHTOOL_GRXCLSRLALL:
		return tsnep_rxnfc_get_all(adapter, cmd, rule_locs);
	default:
		return -EOPNOTSUPP;
	}
}

static int tsnep_ethtool_set_rxnfc(struct net_device *dev,
				   struct ethtool_rxnfc *cmd)
{
	struct tsnep_adapter *adapter = netdev_priv(dev);

	switch (cmd->cmd) {
	case ETHTOOL_SRXCLSRLINS:
		return tsnep_rxnfc_add_rule(adapter, cmd);
	case ETHTOOL_SRXCLSRLDEL:
		return tsnep_rxnfc_del_rule(adapter, cmd);
	default:
		return -EOPNOTSUPP;
	}
}

static int tsnep_ethtool_get_ts_info(struct net_device *dev,
				     struct ethtool_ts_info *info)
{
@@ -287,6 +325,8 @@ const struct ethtool_ops tsnep_ethtool_ops = {
	.get_strings = tsnep_ethtool_get_strings,
	.get_ethtool_stats = tsnep_ethtool_get_ethtool_stats,
	.get_sset_count = tsnep_ethtool_get_sset_count,
	.get_rxnfc = tsnep_ethtool_get_rxnfc,
	.set_rxnfc = tsnep_ethtool_set_rxnfc,
	.get_ts_info = tsnep_ethtool_get_ts_info,
	.get_link_ksettings = phy_ethtool_get_link_ksettings,
	.set_link_ksettings = phy_ethtool_set_link_ksettings,
Loading