aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJerin Jacob <jerinjacobk@gmail.com>2018-12-02 18:17:39 +0530
committerDavid S. Miller <davem@davemloft.net>2018-12-03 16:23:07 -0800
commit7ee74697e557ab9638d7fdcc091c5d25fc78af3d (patch)
treed9c24c5d71a182f0fc0a22fd9cccca3eda864638 /drivers
parentocteontx2-af: Add support for dynamic flow cfg to RSS field generation (diff)
downloadlinux-dev-7ee74697e557ab9638d7fdcc091c5d25fc78af3d.tar.xz
linux-dev-7ee74697e557ab9638d7fdcc091c5d25fc78af3d.zip
octeontx2-af: Add support for runtime RSS algo index reservation
Introduced reserve_flowkey_alg_idx()to reserve RSS algorithm index, it would internally use set_flowkey_fields() to generate fields based on the flow key dynamically. On AF driver init, it would reserve a predefined set RSS algo indexes, which will be available all the time for all the AF driver consumers. The leftover algo indexes can be reserved at runtime through exiting nix_rss_flowkey_cfg mailbox message. The NIX_FLOW_KEY_TYPE_PORT is removed from predefined a set of RSS flow type as it is not used by any consumer. Signed-off-by: Jerin Jacob <jerinj@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/common.h14
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/mbox.h1
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu.h7
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c191
4 files changed, 119 insertions, 94 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/common.h b/drivers/net/ethernet/marvell/octeontx2/af/common.h
index ceb3f1dbede5..72ad04eb8769 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/common.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/common.h
@@ -193,18 +193,4 @@ enum nix_scheduler {
#define DEFAULT_RSS_CONTEXT_GROUP 0
#define MAX_RSS_INDIR_TBL_SIZE 256 /* 1 << Max adder bits */
-/* NIX flow tag algorithm indices, max is 31 */
-enum {
- NIX_FLOW_KEY_ALG_PORT,
- NIX_FLOW_KEY_ALG_IP,
- NIX_FLOW_KEY_ALG_TCP,
- NIX_FLOW_KEY_ALG_UDP,
- NIX_FLOW_KEY_ALG_SCTP,
- NIX_FLOW_KEY_ALG_TCP_UDP,
- NIX_FLOW_KEY_ALG_TCP_SCTP,
- NIX_FLOW_KEY_ALG_UDP_SCTP,
- NIX_FLOW_KEY_ALG_TCP_UDP_SCTP,
- NIX_FLOW_KEY_ALG_MAX,
-};
-
#endif /* COMMON_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index a293091cb414..640a230c43a2 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -415,6 +415,7 @@ enum nix_af_status {
NIX_AF_SMQ_FLUSH_FAILED = -413,
NIX_AF_ERR_LF_RESET = -414,
NIX_AF_ERR_RSS_NOSPC_FIELD = -415,
+ NIX_AF_ERR_RSS_NOSPC_ALGO = -416,
NIX_AF_INVAL_NPA_PF_FUNC = -419,
NIX_AF_INVAL_SSO_PF_FUNC = -420,
};
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index 48dbbaa9dd4d..a0e445d8eb2d 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -164,9 +164,16 @@ struct npc_pkind {
u32 *pfchan_map;
};
+struct nix_flowkey {
+#define NIX_FLOW_KEY_ALG_MAX 32
+ u32 flowkey[NIX_FLOW_KEY_ALG_MAX];
+ int in_use;
+};
+
struct nix_hw {
struct nix_txsch txsch[NIX_TXSCH_LVL_CNT]; /* Tx schedulers */
struct nix_mcast mcast;
+ struct nix_flowkey flowkey;
};
struct rvu_hwinfo {
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index c9f51ab4d875..a1f268652b04 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -1597,57 +1597,16 @@ int rvu_mbox_handler_nix_stats_rst(struct rvu *rvu, struct msg_req *req,
}
/* Returns the ALG index to be set into NPC_RX_ACTION */
-static int get_flowkey_alg_idx(u32 flow_cfg)
+static int get_flowkey_alg_idx(struct nix_hw *nix_hw, u32 flow_cfg)
{
- u32 ip_cfg;
-
- flow_cfg &= ~NIX_FLOW_KEY_TYPE_PORT;
- ip_cfg = NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6;
- if (flow_cfg == ip_cfg)
- return NIX_FLOW_KEY_ALG_IP;
- else if (flow_cfg == (ip_cfg | NIX_FLOW_KEY_TYPE_TCP))
- return NIX_FLOW_KEY_ALG_TCP;
- else if (flow_cfg == (ip_cfg | NIX_FLOW_KEY_TYPE_UDP))
- return NIX_FLOW_KEY_ALG_UDP;
- else if (flow_cfg == (ip_cfg | NIX_FLOW_KEY_TYPE_SCTP))
- return NIX_FLOW_KEY_ALG_SCTP;
- else if (flow_cfg == (ip_cfg | NIX_FLOW_KEY_TYPE_TCP |
- NIX_FLOW_KEY_TYPE_UDP))
- return NIX_FLOW_KEY_ALG_TCP_UDP;
- else if (flow_cfg == (ip_cfg | NIX_FLOW_KEY_TYPE_TCP |
- NIX_FLOW_KEY_TYPE_SCTP))
- return NIX_FLOW_KEY_ALG_TCP_SCTP;
- else if (flow_cfg == (ip_cfg | NIX_FLOW_KEY_TYPE_UDP |
- NIX_FLOW_KEY_TYPE_SCTP))
- return NIX_FLOW_KEY_ALG_UDP_SCTP;
- else if (flow_cfg == (ip_cfg | NIX_FLOW_KEY_TYPE_TCP |
- NIX_FLOW_KEY_TYPE_UDP | NIX_FLOW_KEY_TYPE_SCTP))
- return NIX_FLOW_KEY_ALG_TCP_UDP_SCTP;
-
- return NIX_FLOW_KEY_ALG_PORT;
-}
+ int i;
-int rvu_mbox_handler_nix_rss_flowkey_cfg(struct rvu *rvu,
- struct nix_rss_flowkey_cfg *req,
- struct nix_rss_flowkey_cfg_rsp *rsp)
-{
- struct rvu_hwinfo *hw = rvu->hw;
- u16 pcifunc = req->hdr.pcifunc;
- int alg_idx, nixlf, blkaddr;
+ /* Scan over exiting algo entries to find a match */
+ for (i = 0; i < nix_hw->flowkey.in_use; i++)
+ if (nix_hw->flowkey.flowkey[i] == flow_cfg)
+ return i;
- blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
- if (blkaddr < 0)
- return NIX_AF_ERR_AF_LF_INVALID;
-
- nixlf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0);
- if (nixlf < 0)
- return NIX_AF_ERR_AF_LF_INVALID;
-
- alg_idx = get_flowkey_alg_idx(req->flowkey_cfg);
- rsp->alg_idx = alg_idx;
- rvu_npc_update_flowkey_alg_idx(rvu, pcifunc, nixlf, req->group,
- alg_idx, req->mcam_index);
- return 0;
+ return -ERANGE;
}
static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg)
@@ -1781,71 +1740,141 @@ static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg)
return NIX_AF_ERR_RSS_NOSPC_FIELD;
}
-static void nix_rx_flowkey_alg_cfg(struct rvu *rvu, int blkaddr)
+static int reserve_flowkey_alg_idx(struct rvu *rvu, int blkaddr, u32 flow_cfg)
{
- u64 field[NIX_FLOW_KEY_ALG_MAX][FIELDS_PER_ALG];
- u32 flowkey_cfg, minkey_cfg;
- int alg, fid;
+ u64 field[FIELDS_PER_ALG];
+ struct nix_hw *hw;
+ int fid, rc;
- memset(&field, 0, sizeof(u64) * NIX_FLOW_KEY_ALG_MAX * FIELDS_PER_ALG);
+ hw = get_nix_hw(rvu->hw, blkaddr);
+ if (!hw)
+ return -EINVAL;
- /* Only incoming channel number */
- flowkey_cfg = NIX_FLOW_KEY_TYPE_PORT;
- set_flowkey_fields((void *)&field[NIX_FLOW_KEY_ALG_PORT], flowkey_cfg);
+ /* No room to add new flow hash algoritham */
+ if (hw->flowkey.in_use >= NIX_FLOW_KEY_ALG_MAX)
+ return NIX_AF_ERR_RSS_NOSPC_ALGO;
- /* For a incoming pkt if none of the fields match then flowkey
- * will be zero, hence tag generated will also be zero.
- * RSS entry at rsse_index = NIX_AF_LF()_RSS_GRP()[OFFSET] will
- * be used to queue the packet.
- */
+ /* Generate algo fields for the given flow_cfg */
+ rc = set_flowkey_fields((struct nix_rx_flowkey_alg *)field, flow_cfg);
+ if (rc)
+ return rc;
+
+ /* Update ALGX_FIELDX register with generated fields */
+ for (fid = 0; fid < FIELDS_PER_ALG; fid++)
+ rvu_write64(rvu, blkaddr,
+ NIX_AF_RX_FLOW_KEY_ALGX_FIELDX(hw->flowkey.in_use,
+ fid), field[fid]);
+
+ /* Store the flow_cfg for futher lookup */
+ rc = hw->flowkey.in_use;
+ hw->flowkey.flowkey[rc] = flow_cfg;
+ hw->flowkey.in_use++;
+
+ return rc;
+}
+
+int rvu_mbox_handler_nix_rss_flowkey_cfg(struct rvu *rvu,
+ struct nix_rss_flowkey_cfg *req,
+ struct nix_rss_flowkey_cfg_rsp *rsp)
+{
+ struct rvu_hwinfo *hw = rvu->hw;
+ u16 pcifunc = req->hdr.pcifunc;
+ int alg_idx, nixlf, blkaddr;
+ struct nix_hw *nix_hw;
+
+ blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+ if (blkaddr < 0)
+ return NIX_AF_ERR_AF_LF_INVALID;
+
+ nixlf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0);
+ if (nixlf < 0)
+ return NIX_AF_ERR_AF_LF_INVALID;
+
+ nix_hw = get_nix_hw(rvu->hw, blkaddr);
+ if (!nix_hw)
+ return -EINVAL;
+
+ alg_idx = get_flowkey_alg_idx(nix_hw, req->flowkey_cfg);
+ /* Failed to get algo index from the exiting list, reserve new */
+ if (alg_idx < 0) {
+ alg_idx = reserve_flowkey_alg_idx(rvu, blkaddr,
+ req->flowkey_cfg);
+ if (alg_idx < 0)
+ return alg_idx;
+ }
+ rsp->alg_idx = alg_idx;
+ rvu_npc_update_flowkey_alg_idx(rvu, pcifunc, nixlf, req->group,
+ alg_idx, req->mcam_index);
+ return 0;
+}
+
+static int nix_rx_flowkey_alg_cfg(struct rvu *rvu, int blkaddr)
+{
+ u32 flowkey_cfg, minkey_cfg;
+ int alg, fid, rc;
+
+ /* Disable all flow key algx fieldx */
+ for (alg = 0; alg < NIX_FLOW_KEY_ALG_MAX; alg++) {
+ for (fid = 0; fid < FIELDS_PER_ALG; fid++)
+ rvu_write64(rvu, blkaddr,
+ NIX_AF_RX_FLOW_KEY_ALGX_FIELDX(alg, fid),
+ 0);
+ }
/* IPv4/IPv6 SIP/DIPs */
flowkey_cfg = NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6;
- set_flowkey_fields((void *)&field[NIX_FLOW_KEY_ALG_IP], flowkey_cfg);
+ rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
+ if (rc < 0)
+ return rc;
/* TCPv4/v6 4-tuple, SIP, DIP, Sport, Dport */
minkey_cfg = flowkey_cfg;
flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_TCP;
- set_flowkey_fields((void *)&field[NIX_FLOW_KEY_ALG_TCP], flowkey_cfg);
+ rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
+ if (rc < 0)
+ return rc;
/* UDPv4/v6 4-tuple, SIP, DIP, Sport, Dport */
flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_UDP;
- set_flowkey_fields((void *)&field[NIX_FLOW_KEY_ALG_UDP], flowkey_cfg);
+ rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
+ if (rc < 0)
+ return rc;
/* SCTPv4/v6 4-tuple, SIP, DIP, Sport, Dport */
flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_SCTP;
- set_flowkey_fields((void *)&field[NIX_FLOW_KEY_ALG_SCTP], flowkey_cfg);
+ rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
+ if (rc < 0)
+ return rc;
/* TCP/UDP v4/v6 4-tuple, rest IP pkts 2-tuple */
flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_TCP |
NIX_FLOW_KEY_TYPE_UDP;
- set_flowkey_fields((void *)&field[NIX_FLOW_KEY_ALG_TCP_UDP],
- flowkey_cfg);
+ rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
+ if (rc < 0)
+ return rc;
/* TCP/SCTP v4/v6 4-tuple, rest IP pkts 2-tuple */
flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_TCP |
NIX_FLOW_KEY_TYPE_SCTP;
- set_flowkey_fields((void *)&field[NIX_FLOW_KEY_ALG_TCP_SCTP],
- flowkey_cfg);
+ rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
+ if (rc < 0)
+ return rc;
/* UDP/SCTP v4/v6 4-tuple, rest IP pkts 2-tuple */
flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_UDP |
NIX_FLOW_KEY_TYPE_SCTP;
- set_flowkey_fields((void *)&field[NIX_FLOW_KEY_ALG_UDP_SCTP],
- flowkey_cfg);
+ rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
+ if (rc < 0)
+ return rc;
/* TCP/UDP/SCTP v4/v6 4-tuple, rest IP pkts 2-tuple */
flowkey_cfg = minkey_cfg | NIX_FLOW_KEY_TYPE_TCP |
NIX_FLOW_KEY_TYPE_UDP | NIX_FLOW_KEY_TYPE_SCTP;
- set_flowkey_fields((void *)&field[NIX_FLOW_KEY_ALG_TCP_UDP_SCTP],
- flowkey_cfg);
+ rc = reserve_flowkey_alg_idx(rvu, blkaddr, flowkey_cfg);
+ if (rc < 0)
+ return rc;
- for (alg = 0; alg < NIX_FLOW_KEY_ALG_MAX; alg++) {
- for (fid = 0; fid < FIELDS_PER_ALG; fid++)
- rvu_write64(rvu, blkaddr,
- NIX_AF_RX_FLOW_KEY_ALGX_FIELDX(alg, fid),
- field[alg][fid]);
- }
+ return 0;
}
int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,
@@ -2314,7 +2343,9 @@ int rvu_nix_init(struct rvu *rvu)
rvu_write64(rvu, blkaddr, NIX_AF_RX_DEF_OIP4,
(NPC_LID_LC << 8) | (NPC_LT_LC_IP << 4) | 0x0F);
- nix_rx_flowkey_alg_cfg(rvu, blkaddr);
+ err = nix_rx_flowkey_alg_cfg(rvu, blkaddr);
+ if (err)
+ return err;
/* Initialize CGX/LBK/SDP link credits, min/max pkt lengths */
nix_link_config(rvu, blkaddr);