162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
262306a36Sopenharmony_ci/* Copyright (c) 2017 - 2021 Intel Corporation */
362306a36Sopenharmony_ci#include "osdep.h"
462306a36Sopenharmony_ci#include "type.h"
562306a36Sopenharmony_ci#include "icrdma_hw.h"
662306a36Sopenharmony_ci
762306a36Sopenharmony_cistatic u32 icrdma_regs[IRDMA_MAX_REGS] = {
862306a36Sopenharmony_ci	PFPE_CQPTAIL,
962306a36Sopenharmony_ci	PFPE_CQPDB,
1062306a36Sopenharmony_ci	PFPE_CCQPSTATUS,
1162306a36Sopenharmony_ci	PFPE_CCQPHIGH,
1262306a36Sopenharmony_ci	PFPE_CCQPLOW,
1362306a36Sopenharmony_ci	PFPE_CQARM,
1462306a36Sopenharmony_ci	PFPE_CQACK,
1562306a36Sopenharmony_ci	PFPE_AEQALLOC,
1662306a36Sopenharmony_ci	PFPE_CQPERRCODES,
1762306a36Sopenharmony_ci	PFPE_WQEALLOC,
1862306a36Sopenharmony_ci	GLINT_DYN_CTL(0),
1962306a36Sopenharmony_ci	ICRDMA_DB_ADDR_OFFSET,
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	GLPCI_LBARCTRL,
2262306a36Sopenharmony_ci	GLPE_CPUSTATUS0,
2362306a36Sopenharmony_ci	GLPE_CPUSTATUS1,
2462306a36Sopenharmony_ci	GLPE_CPUSTATUS2,
2562306a36Sopenharmony_ci	PFINT_AEQCTL,
2662306a36Sopenharmony_ci	GLINT_CEQCTL(0),
2762306a36Sopenharmony_ci	VSIQF_PE_CTL1(0),
2862306a36Sopenharmony_ci	PFHMC_PDINV,
2962306a36Sopenharmony_ci	GLHMC_VFPDINV(0),
3062306a36Sopenharmony_ci	GLPE_CRITERR,
3162306a36Sopenharmony_ci	GLINT_RATE(0),
3262306a36Sopenharmony_ci};
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic u64 icrdma_masks[IRDMA_MAX_MASKS] = {
3562306a36Sopenharmony_ci	ICRDMA_CCQPSTATUS_CCQP_DONE,
3662306a36Sopenharmony_ci	ICRDMA_CCQPSTATUS_CCQP_ERR,
3762306a36Sopenharmony_ci	ICRDMA_CQPSQ_STAG_PDID,
3862306a36Sopenharmony_ci	ICRDMA_CQPSQ_CQ_CEQID,
3962306a36Sopenharmony_ci	ICRDMA_CQPSQ_CQ_CQID,
4062306a36Sopenharmony_ci	ICRDMA_COMMIT_FPM_CQCNT,
4162306a36Sopenharmony_ci};
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic u64 icrdma_shifts[IRDMA_MAX_SHIFTS] = {
4462306a36Sopenharmony_ci	ICRDMA_CCQPSTATUS_CCQP_DONE_S,
4562306a36Sopenharmony_ci	ICRDMA_CCQPSTATUS_CCQP_ERR_S,
4662306a36Sopenharmony_ci	ICRDMA_CQPSQ_STAG_PDID_S,
4762306a36Sopenharmony_ci	ICRDMA_CQPSQ_CQ_CEQID_S,
4862306a36Sopenharmony_ci	ICRDMA_CQPSQ_CQ_CQID_S,
4962306a36Sopenharmony_ci	ICRDMA_COMMIT_FPM_CQCNT_S,
5062306a36Sopenharmony_ci};
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/**
5362306a36Sopenharmony_ci * icrdma_ena_irq - Enable interrupt
5462306a36Sopenharmony_ci * @dev: pointer to the device structure
5562306a36Sopenharmony_ci * @idx: vector index
5662306a36Sopenharmony_ci */
5762306a36Sopenharmony_cistatic void icrdma_ena_irq(struct irdma_sc_dev *dev, u32 idx)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	u32 val;
6062306a36Sopenharmony_ci	u32 interval = 0;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	if (dev->ceq_itr && dev->aeq->msix_idx != idx)
6362306a36Sopenharmony_ci		interval = dev->ceq_itr >> 1; /* 2 usec units */
6462306a36Sopenharmony_ci	val = FIELD_PREP(IRDMA_GLINT_DYN_CTL_ITR_INDX, 0) |
6562306a36Sopenharmony_ci	      FIELD_PREP(IRDMA_GLINT_DYN_CTL_INTERVAL, interval) |
6662306a36Sopenharmony_ci	      FIELD_PREP(IRDMA_GLINT_DYN_CTL_INTENA, 1) |
6762306a36Sopenharmony_ci	      FIELD_PREP(IRDMA_GLINT_DYN_CTL_CLEARPBA, 1);
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	if (dev->hw_attrs.uk_attrs.hw_rev != IRDMA_GEN_1)
7062306a36Sopenharmony_ci		writel(val, dev->hw_regs[IRDMA_GLINT_DYN_CTL] + idx);
7162306a36Sopenharmony_ci	else
7262306a36Sopenharmony_ci		writel(val, dev->hw_regs[IRDMA_GLINT_DYN_CTL] + (idx - 1));
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci/**
7662306a36Sopenharmony_ci * icrdma_disable_irq - Disable interrupt
7762306a36Sopenharmony_ci * @dev: pointer to the device structure
7862306a36Sopenharmony_ci * @idx: vector index
7962306a36Sopenharmony_ci */
8062306a36Sopenharmony_cistatic void icrdma_disable_irq(struct irdma_sc_dev *dev, u32 idx)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	if (dev->hw_attrs.uk_attrs.hw_rev != IRDMA_GEN_1)
8362306a36Sopenharmony_ci		writel(0, dev->hw_regs[IRDMA_GLINT_DYN_CTL] + idx);
8462306a36Sopenharmony_ci	else
8562306a36Sopenharmony_ci		writel(0, dev->hw_regs[IRDMA_GLINT_DYN_CTL] + (idx - 1));
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/**
8962306a36Sopenharmony_ci * icrdma_cfg_ceq- Configure CEQ interrupt
9062306a36Sopenharmony_ci * @dev: pointer to the device structure
9162306a36Sopenharmony_ci * @ceq_id: Completion Event Queue ID
9262306a36Sopenharmony_ci * @idx: vector index
9362306a36Sopenharmony_ci * @enable: True to enable, False disables
9462306a36Sopenharmony_ci */
9562306a36Sopenharmony_cistatic void icrdma_cfg_ceq(struct irdma_sc_dev *dev, u32 ceq_id, u32 idx,
9662306a36Sopenharmony_ci			   bool enable)
9762306a36Sopenharmony_ci{
9862306a36Sopenharmony_ci	u32 reg_val;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	reg_val = FIELD_PREP(IRDMA_GLINT_CEQCTL_CAUSE_ENA, enable) |
10162306a36Sopenharmony_ci		  FIELD_PREP(IRDMA_GLINT_CEQCTL_MSIX_INDX, idx) |
10262306a36Sopenharmony_ci		  FIELD_PREP(IRDMA_GLINT_CEQCTL_ITR_INDX, 3);
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	writel(reg_val, dev->hw_regs[IRDMA_GLINT_CEQCTL] + ceq_id);
10562306a36Sopenharmony_ci}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistatic const struct irdma_irq_ops icrdma_irq_ops = {
10862306a36Sopenharmony_ci	.irdma_cfg_aeq = irdma_cfg_aeq,
10962306a36Sopenharmony_ci	.irdma_cfg_ceq = icrdma_cfg_ceq,
11062306a36Sopenharmony_ci	.irdma_dis_irq = icrdma_disable_irq,
11162306a36Sopenharmony_ci	.irdma_en_irq = icrdma_ena_irq,
11262306a36Sopenharmony_ci};
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistatic const struct irdma_hw_stat_map icrdma_hw_stat_map[] = {
11562306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RXVLANERR]	=	{   0, 32, IRDMA_MAX_STATS_24 },
11662306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4RXOCTS] =	{   8,  0, IRDMA_MAX_STATS_48 },
11762306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4RXPKTS] =	{  16,  0, IRDMA_MAX_STATS_48 },
11862306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4RXDISCARD] =	{  24, 32, IRDMA_MAX_STATS_32 },
11962306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4RXTRUNC] =	{  24,  0, IRDMA_MAX_STATS_32 },
12062306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4RXFRAGS] =	{  32,  0, IRDMA_MAX_STATS_48 },
12162306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4RXMCOCTS] =	{  40,  0, IRDMA_MAX_STATS_48 },
12262306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4RXMCPKTS] =	{  48,  0, IRDMA_MAX_STATS_48 },
12362306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6RXOCTS] =	{  56,  0, IRDMA_MAX_STATS_48 },
12462306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6RXPKTS] =	{  64,  0, IRDMA_MAX_STATS_48 },
12562306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6RXDISCARD] =	{  72, 32, IRDMA_MAX_STATS_32 },
12662306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6RXTRUNC] =	{  72,  0, IRDMA_MAX_STATS_32 },
12762306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6RXFRAGS] =	{  80,  0, IRDMA_MAX_STATS_48 },
12862306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6RXMCOCTS] =	{  88,  0, IRDMA_MAX_STATS_48 },
12962306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6RXMCPKTS] =	{  96,  0, IRDMA_MAX_STATS_48 },
13062306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4TXOCTS] =	{ 104,  0, IRDMA_MAX_STATS_48 },
13162306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4TXPKTS] =	{ 112,  0, IRDMA_MAX_STATS_48 },
13262306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4TXFRAGS] =	{ 120,  0, IRDMA_MAX_STATS_48 },
13362306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4TXMCOCTS] =	{ 128,  0, IRDMA_MAX_STATS_48 },
13462306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4TXMCPKTS] =	{ 136,  0, IRDMA_MAX_STATS_48 },
13562306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6TXOCTS] =	{ 144,  0, IRDMA_MAX_STATS_48 },
13662306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6TXPKTS] =	{ 152,  0, IRDMA_MAX_STATS_48 },
13762306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6TXFRAGS] =	{ 160,  0, IRDMA_MAX_STATS_48 },
13862306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6TXMCOCTS] =	{ 168,  0, IRDMA_MAX_STATS_48 },
13962306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6TXMCPKTS] =	{ 176,  0, IRDMA_MAX_STATS_48 },
14062306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP4TXNOROUTE] =	{ 184, 32, IRDMA_MAX_STATS_24 },
14162306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_IP6TXNOROUTE] =	{ 184,  0, IRDMA_MAX_STATS_24 },
14262306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_TCPRXSEGS] =	{ 192, 32, IRDMA_MAX_STATS_48 },
14362306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_TCPRXOPTERR] =	{ 200, 32, IRDMA_MAX_STATS_24 },
14462306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_TCPRXPROTOERR] =	{ 200,  0, IRDMA_MAX_STATS_24 },
14562306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_TCPTXSEG] =	{ 208,  0, IRDMA_MAX_STATS_48 },
14662306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_TCPRTXSEG] =	{ 216, 32, IRDMA_MAX_STATS_32 },
14762306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_UDPRXPKTS] =	{ 224,  0, IRDMA_MAX_STATS_48 },
14862306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_UDPTXPKTS] =	{ 232,  0, IRDMA_MAX_STATS_48 },
14962306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RDMARXWRS] =	{ 240,  0, IRDMA_MAX_STATS_48 },
15062306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RDMARXRDS] =	{ 248,  0, IRDMA_MAX_STATS_48 },
15162306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RDMARXSNDS] =	{ 256,  0, IRDMA_MAX_STATS_48 },
15262306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RDMATXWRS] =	{ 264,  0, IRDMA_MAX_STATS_48 },
15362306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RDMATXRDS] =	{ 272,  0, IRDMA_MAX_STATS_48 },
15462306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RDMATXSNDS] =	{ 280,  0, IRDMA_MAX_STATS_48 },
15562306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RDMAVBND] =	{ 288,  0, IRDMA_MAX_STATS_48 },
15662306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RDMAVINV] =	{ 296,  0, IRDMA_MAX_STATS_48 },
15762306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RXNPECNMARKEDPKTS] = { 304,  0, IRDMA_MAX_STATS_56 },
15862306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RXRPCNPIGNORED] =	{ 312, 32, IRDMA_MAX_STATS_24 },
15962306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_RXRPCNPHANDLED] =	{ 312,  0, IRDMA_MAX_STATS_32 },
16062306a36Sopenharmony_ci	[IRDMA_HW_STAT_INDEX_TXNPCNPSENT] =	{ 320,  0, IRDMA_MAX_STATS_32 },
16162306a36Sopenharmony_ci};
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_civoid icrdma_init_hw(struct irdma_sc_dev *dev)
16462306a36Sopenharmony_ci{
16562306a36Sopenharmony_ci	int i;
16662306a36Sopenharmony_ci	u8 __iomem *hw_addr;
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	for (i = 0; i < IRDMA_MAX_REGS; ++i) {
16962306a36Sopenharmony_ci		hw_addr = dev->hw->hw_addr;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci		if (i == IRDMA_DB_ADDR_OFFSET)
17262306a36Sopenharmony_ci			hw_addr = NULL;
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci		dev->hw_regs[i] = (u32 __iomem *)(hw_addr + icrdma_regs[i]);
17562306a36Sopenharmony_ci	}
17662306a36Sopenharmony_ci	dev->hw_attrs.max_hw_vf_fpm_id = IRDMA_MAX_VF_FPM_ID;
17762306a36Sopenharmony_ci	dev->hw_attrs.first_hw_vf_fpm_id = IRDMA_FIRST_VF_FPM_ID;
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	for (i = 0; i < IRDMA_MAX_SHIFTS; ++i)
18062306a36Sopenharmony_ci		dev->hw_shifts[i] = icrdma_shifts[i];
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	for (i = 0; i < IRDMA_MAX_MASKS; ++i)
18362306a36Sopenharmony_ci		dev->hw_masks[i] = icrdma_masks[i];
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	dev->wqe_alloc_db = dev->hw_regs[IRDMA_WQEALLOC];
18662306a36Sopenharmony_ci	dev->cq_arm_db = dev->hw_regs[IRDMA_CQARM];
18762306a36Sopenharmony_ci	dev->aeq_alloc_db = dev->hw_regs[IRDMA_AEQALLOC];
18862306a36Sopenharmony_ci	dev->cqp_db = dev->hw_regs[IRDMA_CQPDB];
18962306a36Sopenharmony_ci	dev->cq_ack_db = dev->hw_regs[IRDMA_CQACK];
19062306a36Sopenharmony_ci	dev->irq_ops = &icrdma_irq_ops;
19162306a36Sopenharmony_ci	dev->hw_attrs.page_size_cap = SZ_4K | SZ_2M | SZ_1G;
19262306a36Sopenharmony_ci	dev->hw_stats_map = icrdma_hw_stat_map;
19362306a36Sopenharmony_ci	dev->hw_attrs.max_hw_ird = ICRDMA_MAX_IRD_SIZE;
19462306a36Sopenharmony_ci	dev->hw_attrs.max_hw_ord = ICRDMA_MAX_ORD_SIZE;
19562306a36Sopenharmony_ci	dev->hw_attrs.max_stat_inst = ICRDMA_MAX_STATS_COUNT;
19662306a36Sopenharmony_ci	dev->hw_attrs.max_stat_idx = IRDMA_HW_STAT_INDEX_MAX_GEN_2;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	dev->hw_attrs.uk_attrs.min_hw_wq_size = ICRDMA_MIN_WQ_SIZE;
19962306a36Sopenharmony_ci	dev->hw_attrs.uk_attrs.max_hw_sq_chunk = IRDMA_MAX_QUANTA_PER_WR;
20062306a36Sopenharmony_ci	dev->hw_attrs.uk_attrs.feature_flags |= IRDMA_FEATURE_RTS_AE |
20162306a36Sopenharmony_ci						IRDMA_FEATURE_CQ_RESIZE;
20262306a36Sopenharmony_ci}
203