Commit b1e0b124 authored by David S. Miller's avatar David S. Miller

Merge branch 'xgene-multiq'

Iyappan Subramanian says:

====================
Add support for Classifier and RSS

This patch set enables,

(i) Classifier engine that is used for parsing
through the packet and extracting a search string that is then used
to search a database to find associative data.

(ii) Receive Side Scaling (RSS) that does dynamic load
balancing of the CPUs by controlling the number of messages enqueued
per CPU though the help of Toeplitz Hash function of 4-tuple of
source TCP/UDP port, destination TCP/UDP port, source IPV4 address and
destination IPV4 address.

(iii) Multi queue, to make advantage of RSS

v3: Address review comments from v2
    - reordered local variables from longest to shortlest line

v2: Address review comments from v1
    - fix kbuild warning
    - add default coalescing

v1:
    - Initial version
====================
Signed-off-by: default avatarIyappan Subramanian <isubramanian@apm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e4999f25 0d2c2515
......@@ -621,7 +621,13 @@ xgenet1: ethernet@1f620000 {
<0x0 0x1f600000 0x0 0Xd100>,
<0x0 0x20000000 0x0 0X220000>;
interrupts = <0 108 4>,
<0 109 4>;
<0 109 4>,
<0 110 4>,
<0 111 4>,
<0 112 4>,
<0 113 4>,
<0 114 4>,
<0 115 4>;
port-id = <1>;
dma-coherent;
clocks = <&xge1clk 0>;
......
......@@ -958,7 +958,13 @@ xgenet: ethernet@1f610000 {
<0x0 0x18000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
interrupts = <0x0 0x60 0x4>,
<0x0 0x61 0x4>;
<0x0 0x61 0x4>,
<0x0 0x62 0x4>,
<0x0 0x63 0x4>,
<0x0 0x64 0x4>,
<0x0 0x65 0x4>,
<0x0 0x66 0x4>,
<0x0 0x67 0x4>;
dma-coherent;
clocks = <&xge0clk 0>;
/* mac address will be overwritten by the bootloader */
......
......@@ -3,5 +3,6 @@
#
xgene-enet-objs := xgene_enet_hw.o xgene_enet_sgmac.o xgene_enet_xgmac.o \
xgene_enet_main.o xgene_enet_ring2.o xgene_enet_ethtool.o
xgene_enet_main.o xgene_enet_ring2.o xgene_enet_ethtool.o \
xgene_enet_cle.o
obj-$(CONFIG_NET_XGENE) += xgene-enet.o
This diff is collapsed.
/* Applied Micro X-Gene SoC Ethernet Classifier structures
*
* Copyright (c) 2016, Applied Micro Circuits Corporation
* Authors: Khuong Dinh <kdinh@apm.com>
* Tanmay Inamdar <tinamdar@apm.com>
* Iyappan Subramanian <isubramanian@apm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __XGENE_ENET_CLE_H__
#define __XGENE_ENET_CLE_H__
#include <linux/io.h>
#include <linux/random.h>
/* Register offsets */
#define INDADDR 0x04
#define INDCMD 0x08
#define INDCMD_STATUS 0x0c
#define DATA_RAM0 0x10
#define SNPTR0 0x0100
#define SPPTR0 0x0104
#define DFCLSRESDBPTR0 0x0108
#define DFCLSRESDB00 0x010c
#define RSS_CTRL0 0x0000013c
#define CLE_CMD_TO 10 /* ms */
#define CLE_PKTRAM_SIZE 256 /* bytes */
#define CLE_PORT_OFFSET 0x200
#define CLE_DRAM_REGS 17
#define CLE_DN_TYPE_LEN 2
#define CLE_DN_TYPE_POS 0
#define CLE_DN_LASTN_LEN 1
#define CLE_DN_LASTN_POS 2
#define CLE_DN_HLS_LEN 1
#define CLE_DN_HLS_POS 3
#define CLE_DN_EXT_LEN 2
#define CLE_DN_EXT_POS 4
#define CLE_DN_BSTOR_LEN 2
#define CLE_DN_BSTOR_POS 6
#define CLE_DN_SBSTOR_LEN 2
#define CLE_DN_SBSTOR_POS 8
#define CLE_DN_RPTR_LEN 12
#define CLE_DN_RPTR_POS 12
#define CLE_BR_VALID_LEN 1
#define CLE_BR_VALID_POS 0
#define CLE_BR_NPPTR_LEN 9
#define CLE_BR_NPPTR_POS 1
#define CLE_BR_JB_LEN 1
#define CLE_BR_JB_POS 10
#define CLE_BR_JR_LEN 1
#define CLE_BR_JR_POS 11
#define CLE_BR_OP_LEN 3
#define CLE_BR_OP_POS 12
#define CLE_BR_NNODE_LEN 9
#define CLE_BR_NNODE_POS 15
#define CLE_BR_NBR_LEN 5
#define CLE_BR_NBR_POS 24
#define CLE_BR_DATA_LEN 16
#define CLE_BR_DATA_POS 0
#define CLE_BR_MASK_LEN 16
#define CLE_BR_MASK_POS 16
#define CLE_KN_PRIO_POS 0
#define CLE_KN_PRIO_LEN 3
#define CLE_KN_RPTR_POS 3
#define CLE_KN_RPTR_LEN 10
#define CLE_TYPE_POS 0
#define CLE_TYPE_LEN 2
#define CLE_DSTQIDL_POS 25
#define CLE_DSTQIDL_LEN 7
#define CLE_DSTQIDH_POS 0
#define CLE_DSTQIDH_LEN 5
#define CLE_FPSEL_POS 21
#define CLE_FPSEL_LEN 4
#define CLE_PRIORITY_POS 5
#define CLE_PRIORITY_LEN 3
#define JMP_ABS 0
#define JMP_REL 1
#define JMP_FW 0
#define JMP_BW 1
enum xgene_cle_ptree_nodes {
PKT_TYPE_NODE,
PKT_PROT_NODE,
RSS_IPV4_TCP_NODE,
RSS_IPV4_UDP_NODE,
LAST_NODE,
MAX_NODES
};
enum xgene_cle_byte_store {
NO_BYTE,
FIRST_BYTE,
SECOND_BYTE,
BOTH_BYTES
};
/* Preclassification operation types */
enum xgene_cle_node_type {
INV,
KN,
EWDN,
RES_NODE
};
/* Preclassification operation types */
enum xgene_cle_op_type {
EQT,
NEQT,
LTEQT,
GTEQT,
AND,
NAND
};
enum xgene_cle_parser {
PARSER0,
PARSER1,
PARSER2,
PARSER_ALL
};
#define XGENE_CLE_DRAM(type) (((type) & 0xf) << 28)
enum xgene_cle_dram_type {
PKT_RAM,
RSS_IDT,
RSS_IPV4_HASH_SKEY,
PTREE_RAM = 0xc,
AVL_RAM,
DB_RAM
};
enum xgene_cle_cmd_type {
CLE_CMD_WR = 1,
CLE_CMD_RD = 2,
CLE_CMD_AVL_ADD = 8,
CLE_CMD_AVL_DEL = 16,
CLE_CMD_AVL_SRCH = 32
};
enum xgene_cle_ipv4_rss_hashtype {
RSS_IPV4_8B,
RSS_IPV4_12B,
};
enum xgene_cle_prot_type {
XGENE_CLE_TCP,
XGENE_CLE_UDP,
XGENE_CLE_ESP,
XGENE_CLE_OTHER
};
enum xgene_cle_prot_version {
XGENE_CLE_IPV4,
};
enum xgene_cle_ptree_dbptrs {
DB_RES_DROP,
DB_RES_DEF,
DB_RES_ACCEPT,
DB_MAX_PTRS
};
/* RSS sideband signal info */
#define SB_IPFRAG_POS 0
#define SB_IPFRAG_LEN 1
#define SB_IPPROT_POS 1
#define SB_IPPROT_LEN 2
#define SB_IPVER_POS 3
#define SB_IPVER_LEN 1
#define SB_HDRLEN_POS 4
#define SB_HDRLEN_LEN 12
/* RSS indirection table */
#define XGENE_CLE_IDT_ENTRIES 128
#define IDT_DSTQID_POS 0
#define IDT_DSTQID_LEN 12
#define IDT_FPSEL_POS 12
#define IDT_FPSEL_LEN 4
#define IDT_NFPSEL_POS 16
#define IDT_NFPSEL_LEN 4
struct xgene_cle_ptree_branch {
bool valid;
u16 next_packet_pointer;
bool jump_bw;
bool jump_rel;
u8 operation;
u16 next_node;
u8 next_branch;
u16 data;
u16 mask;
};
struct xgene_cle_ptree_ewdn {
u8 node_type;
bool last_node;
bool hdr_len_store;
u8 hdr_extn;
u8 byte_store;
u8 search_byte_store;
u16 result_pointer;
u8 num_branches;
struct xgene_cle_ptree_branch branch[6];
};
struct xgene_cle_ptree_key {
u8 priority;
u16 result_pointer;
};
struct xgene_cle_ptree_kn {
u8 node_type;
u8 num_keys;
struct xgene_cle_ptree_key key[32];
};
struct xgene_cle_dbptr {
u8 split_boundary;
u8 mirror_nxtfpsel;
u8 mirror_fpsel;
u16 mirror_dstqid;
u8 drop;
u8 mirror;
u8 hdr_data_split;
u64 hopinfomsbs;
u8 DR;
u8 HR;
u64 hopinfomlsbs;
u16 h0enq_num;
u8 h0fpsel;
u8 nxtfpsel;
u8 fpsel;
u16 dstqid;
u8 cle_priority;
u8 cle_flowgroup;
u8 cle_perflow;
u8 cle_insert_timestamp;
u8 stash;
u8 in;
u8 perprioen;
u8 perflowgroupen;
u8 perflowen;
u8 selhash;
u8 selhdrext;
u8 mirror_nxtfpsel_msb;
u8 mirror_fpsel_msb;
u8 hfpsel_msb;
u8 nxtfpsel_msb;
u8 fpsel_msb;
};
struct xgene_cle_ptree {
struct xgene_cle_ptree_ewdn *dn;
struct xgene_cle_ptree_kn *kn;
struct xgene_cle_dbptr *dbptr;
u32 num_dn;
u32 num_kn;
u32 num_dbptr;
u32 start_node;
u32 start_pkt;
u32 start_dbptr;
};
struct xgene_enet_cle {
void __iomem *base;
struct xgene_cle_ptree ptree;
enum xgene_cle_parser active_parser;
u32 parsers;
u32 max_nodes;
u32 max_dbptrs;
u32 jump_bytes;
};
extern struct xgene_cle_ops xgene_cle3in_ops;
#endif /* __XGENE_ENET_CLE_H__ */
......@@ -204,6 +204,17 @@ static u32 xgene_enet_ring_len(struct xgene_enet_desc_ring *ring)
return num_msgs;
}
static void xgene_enet_setup_coalescing(struct xgene_enet_desc_ring *ring)
{
u32 data = 0x7777;
xgene_enet_ring_wr32(ring, CSR_PBM_COAL, 0x8e);
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK1, data);
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK2, data << 16);
xgene_enet_ring_wr32(ring, CSR_THRESHOLD0_SET1, 0x40);
xgene_enet_ring_wr32(ring, CSR_THRESHOLD1_SET1, 0x80);
}
void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
struct xgene_enet_pdata *pdata,
enum xgene_enet_err_code status)
......@@ -892,4 +903,5 @@ struct xgene_ring_ops xgene_ring1_ops = {
.clear = xgene_enet_clear_ring,
.wr_cmd = xgene_enet_wr_cmd,
.len = xgene_enet_ring_len,
.coalesce = xgene_enet_setup_coalescing,
};
......@@ -54,6 +54,11 @@ enum xgene_enet_rm {
#define IS_BUFFER_POOL BIT(20)
#define PREFETCH_BUF_EN BIT(21)
#define CSR_RING_ID_BUF 0x000c
#define CSR_PBM_COAL 0x0014
#define CSR_PBM_CTICK1 0x001c
#define CSR_PBM_CTICK2 0x0020
#define CSR_THRESHOLD0_SET1 0x0030
#define CSR_THRESHOLD1_SET1 0x0034
#define CSR_RING_NE_INT_MODE 0x017c
#define CSR_RING_CONFIG 0x006c
#define CSR_RING_WR_BASE 0x0070
......@@ -101,6 +106,7 @@ enum xgene_enet_rm {
#define MAC_OFFSET 0x30
#define BLOCK_ETH_CSR_OFFSET 0x2000
#define BLOCK_ETH_CLE_CSR_OFFSET 0x6000
#define BLOCK_ETH_RING_IF_OFFSET 0x9000
#define BLOCK_ETH_CLKRST_CSR_OFFSET 0xc000
#define BLOCK_ETH_DIAG_CSR_OFFSET 0xD000
......
......@@ -36,6 +36,7 @@
#include <linux/if_vlan.h>
#include <linux/phy.h>
#include "xgene_enet_hw.h"
#include "xgene_enet_cle.h"
#include "xgene_enet_ring2.h"
#define XGENE_DRV_VERSION "v1.0"
......@@ -48,6 +49,11 @@
#define XGENE_ENET_MSS 1448
#define XGENE_MIN_ENET_FRAME_SIZE 60
#define XGENE_MAX_ENET_IRQ 8
#define XGENE_NUM_RX_RING 4
#define XGENE_NUM_TX_RING 4
#define XGENE_NUM_TXC_RING 4
#define START_CPU_BUFNUM_0 0
#define START_ETH_BUFNUM_0 2
#define START_BP_BUFNUM_0 0x22
......@@ -72,7 +78,6 @@
#define X2_START_RING_NUM_1 256
#define IRQ_ID_SIZE 16
#define XGENE_MAX_TXC_RINGS 1
#define PHY_POLL_LINK_ON (10 * HZ)
#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
......@@ -102,6 +107,7 @@ struct xgene_enet_desc_ring {
void *irq_mbox_addr;
u16 dst_ring_num;
u8 nbufpool;
u8 index;
struct sk_buff *(*rx_skb);
struct sk_buff *(*cp_skb);
dma_addr_t *frag_dma_addr;
......@@ -143,6 +149,11 @@ struct xgene_ring_ops {
void (*clear)(struct xgene_enet_desc_ring *);
void (*wr_cmd)(struct xgene_enet_desc_ring *, int);
u32 (*len)(struct xgene_enet_desc_ring *);
void (*coalesce)(struct xgene_enet_desc_ring *);
};
struct xgene_cle_ops {
int (*cle_init)(struct xgene_enet_pdata *pdata);
};
/* ethernet private data */
......@@ -154,15 +165,16 @@ struct xgene_enet_pdata {
struct clk *clk;
struct platform_device *pdev;
enum xgene_enet_id enet_id;
struct xgene_enet_desc_ring *tx_ring;
struct xgene_enet_desc_ring *rx_ring;
u16 tx_level;
u16 txc_level;
struct xgene_enet_desc_ring *tx_ring[XGENE_NUM_TX_RING];
struct xgene_enet_desc_ring *rx_ring[XGENE_NUM_RX_RING];
u16 tx_level[XGENE_NUM_TX_RING];
u16 txc_level[XGENE_NUM_TX_RING];
char *dev_name;
u32 rx_buff_cnt;
u32 tx_qcnt_hi;
u32 rx_irq;
u32 txc_irq;
u32 irqs[XGENE_MAX_ENET_IRQ];
u8 rxq_cnt;
u8 txq_cnt;
u8 cq_cnt;
void __iomem *eth_csr_addr;
void __iomem *eth_ring_if_addr;
......@@ -174,10 +186,12 @@ struct xgene_enet_pdata {
void __iomem *ring_cmd_addr;
int phy_mode;
enum xgene_enet_rm rm;
struct xgene_enet_cle cle;
struct rtnl_link_stats64 stats;
const struct xgene_mac_ops *mac_ops;
const struct xgene_port_ops *port_ops;
struct xgene_ring_ops *ring_ops;
struct xgene_cle_ops *cle_ops;
struct delayed_work link_work;
u32 port_id;
u8 cpu_bufnum;
......@@ -229,6 +243,13 @@ static inline struct device *ndev_to_dev(struct net_device *ndev)
return ndev->dev.parent;
}
static inline u16 xgene_enet_dst_ring_num(struct xgene_enet_desc_ring *ring)
{
struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev);
return ((u16)pdata->rm << 10) | ring->num;
}
void xgene_enet_set_ethtool_ops(struct net_device *netdev);
#endif /* __XGENE_ENET_MAIN_H__ */
......@@ -190,6 +190,17 @@ static u32 xgene_enet_ring_len(struct xgene_enet_desc_ring *ring)
return num_msgs;
}
static void xgene_enet_setup_coalescing(struct xgene_enet_desc_ring *ring)
{
u32 data = 0x7777;
xgene_enet_ring_wr32(ring, CSR_PBM_COAL, 0x8e);
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK1, data);
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK2, data << 16);
xgene_enet_ring_wr32(ring, CSR_THRESHOLD0_SET1, 0x40);
xgene_enet_ring_wr32(ring, CSR_THRESHOLD1_SET1, 0x80);
}
struct xgene_ring_ops xgene_ring2_ops = {
.num_ring_config = X2_NUM_RING_CONFIG,
.num_ring_id_shift = 13,
......@@ -197,4 +208,5 @@ struct xgene_ring_ops xgene_ring2_ops = {
.clear = xgene_enet_clear_ring,
.wr_cmd = xgene_enet_wr_cmd,
.len = xgene_enet_ring_len,
.coalesce = xgene_enet_setup_coalescing,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment