1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2015 - 2021 Intel Corporation */
8 static u32 i40iw_regs
[IRDMA_MAX_REGS
] = {
17 I40E_PFPE_CQPERRCODES
,
19 I40E_PFINT_DYN_CTLN(0),
30 I40E_GLHMC_VFPDINV(0),
32 0xffffffff /* PFINT_RATEN not used in FPK */
35 static u32 i40iw_stat_offsets
[] = {
36 I40E_GLPES_PFIP4RXDISCARD(0),
37 I40E_GLPES_PFIP4RXTRUNC(0),
38 I40E_GLPES_PFIP4TXNOROUTE(0),
39 I40E_GLPES_PFIP6RXDISCARD(0),
40 I40E_GLPES_PFIP6RXTRUNC(0),
41 I40E_GLPES_PFIP6TXNOROUTE(0),
42 I40E_GLPES_PFTCPRTXSEG(0),
43 I40E_GLPES_PFTCPRXOPTERR(0),
44 I40E_GLPES_PFTCPRXPROTOERR(0),
45 I40E_GLPES_PFRXVLANERR(0),
47 I40E_GLPES_PFIP4RXOCTSLO(0),
48 I40E_GLPES_PFIP4RXPKTSLO(0),
49 I40E_GLPES_PFIP4RXFRAGSLO(0),
50 I40E_GLPES_PFIP4RXMCPKTSLO(0),
51 I40E_GLPES_PFIP4TXOCTSLO(0),
52 I40E_GLPES_PFIP4TXPKTSLO(0),
53 I40E_GLPES_PFIP4TXFRAGSLO(0),
54 I40E_GLPES_PFIP4TXMCPKTSLO(0),
55 I40E_GLPES_PFIP6RXOCTSLO(0),
56 I40E_GLPES_PFIP6RXPKTSLO(0),
57 I40E_GLPES_PFIP6RXFRAGSLO(0),
58 I40E_GLPES_PFIP6RXMCPKTSLO(0),
59 I40E_GLPES_PFIP6TXOCTSLO(0),
60 I40E_GLPES_PFIP6TXPKTSLO(0),
61 I40E_GLPES_PFIP6TXFRAGSLO(0),
62 I40E_GLPES_PFIP6TXMCPKTSLO(0),
63 I40E_GLPES_PFTCPRXSEGSLO(0),
64 I40E_GLPES_PFTCPTXSEGLO(0),
65 I40E_GLPES_PFRDMARXRDSLO(0),
66 I40E_GLPES_PFRDMARXSNDSLO(0),
67 I40E_GLPES_PFRDMARXWRSLO(0),
68 I40E_GLPES_PFRDMATXRDSLO(0),
69 I40E_GLPES_PFRDMATXSNDSLO(0),
70 I40E_GLPES_PFRDMATXWRSLO(0),
71 I40E_GLPES_PFRDMAVBNDLO(0),
72 I40E_GLPES_PFRDMAVINVLO(0),
73 I40E_GLPES_PFIP4RXMCOCTSLO(0),
74 I40E_GLPES_PFIP4TXMCOCTSLO(0),
75 I40E_GLPES_PFIP6RXMCOCTSLO(0),
76 I40E_GLPES_PFIP6TXMCOCTSLO(0),
77 I40E_GLPES_PFUDPRXPKTSLO(0),
78 I40E_GLPES_PFUDPTXPKTSLO(0)
81 static u64 i40iw_masks
[IRDMA_MAX_MASKS
] = {
82 I40E_PFPE_CCQPSTATUS_CCQP_DONE
,
83 I40E_PFPE_CCQPSTATUS_CCQP_ERR
,
87 I40E_COMMIT_FPM_CQCNT
,
90 static u64 i40iw_shifts
[IRDMA_MAX_SHIFTS
] = {
91 I40E_PFPE_CCQPSTATUS_CCQP_DONE_S
,
92 I40E_PFPE_CCQPSTATUS_CCQP_ERR_S
,
93 I40E_CQPSQ_STAG_PDID_S
,
94 I40E_CQPSQ_CQ_CEQID_S
,
96 I40E_COMMIT_FPM_CQCNT_S
,
100 * i40iw_config_ceq- Configure CEQ interrupt
101 * @dev: pointer to the device structure
102 * @ceq_id: Completion Event Queue ID
104 * @enable: Enable CEQ interrupt when true
106 static void i40iw_config_ceq(struct irdma_sc_dev
*dev
, u32 ceq_id
, u32 idx
,
111 reg_val
= FIELD_PREP(I40E_PFINT_LNKLSTN_FIRSTQ_INDX
, ceq_id
) |
112 FIELD_PREP(I40E_PFINT_LNKLSTN_FIRSTQ_TYPE
, QUEUE_TYPE_CEQ
);
113 wr32(dev
->hw
, I40E_PFINT_LNKLSTN(idx
- 1), reg_val
);
115 reg_val
= FIELD_PREP(I40E_PFINT_DYN_CTLN_ITR_INDX
, 0x3) |
116 FIELD_PREP(I40E_PFINT_DYN_CTLN_INTENA
, 0x1);
117 wr32(dev
->hw
, I40E_PFINT_DYN_CTLN(idx
- 1), reg_val
);
119 reg_val
= FIELD_PREP(IRDMA_GLINT_CEQCTL_CAUSE_ENA
, enable
) |
120 FIELD_PREP(IRDMA_GLINT_CEQCTL_MSIX_INDX
, idx
) |
121 FIELD_PREP(I40E_PFINT_CEQCTL_NEXTQ_INDX
, NULL_QUEUE_INDEX
) |
122 FIELD_PREP(IRDMA_GLINT_CEQCTL_ITR_INDX
, 0x3);
124 wr32(dev
->hw
, i40iw_regs
[IRDMA_GLINT_CEQCTL
] + 4 * ceq_id
, reg_val
);
128 * i40iw_ena_irq - Enable interrupt
129 * @dev: pointer to the device structure
132 static void i40iw_ena_irq(struct irdma_sc_dev
*dev
, u32 idx
)
136 val
= FIELD_PREP(IRDMA_GLINT_DYN_CTL_INTENA
, 0x1) |
137 FIELD_PREP(IRDMA_GLINT_DYN_CTL_CLEARPBA
, 0x1) |
138 FIELD_PREP(IRDMA_GLINT_DYN_CTL_ITR_INDX
, 0x3);
139 wr32(dev
->hw
, i40iw_regs
[IRDMA_GLINT_DYN_CTL
] + 4 * (idx
- 1), val
);
143 * i40iw_disable_irq - Disable interrupt
144 * @dev: pointer to the device structure
147 static void i40iw_disable_irq(struct irdma_sc_dev
*dev
, u32 idx
)
149 wr32(dev
->hw
, i40iw_regs
[IRDMA_GLINT_DYN_CTL
] + 4 * (idx
- 1), 0);
152 static const struct irdma_irq_ops i40iw_irq_ops
= {
153 .irdma_cfg_aeq
= irdma_cfg_aeq
,
154 .irdma_cfg_ceq
= i40iw_config_ceq
,
155 .irdma_dis_irq
= i40iw_disable_irq
,
156 .irdma_en_irq
= i40iw_ena_irq
,
159 static const struct irdma_hw_stat_map i40iw_hw_stat_map
[] = {
160 [IRDMA_HW_STAT_INDEX_RXVLANERR
] = { 0, 0, IRDMA_MAX_STATS_24
},
161 [IRDMA_HW_STAT_INDEX_IP4RXOCTS
] = { 8, 0, IRDMA_MAX_STATS_48
},
162 [IRDMA_HW_STAT_INDEX_IP4RXPKTS
] = { 16, 0, IRDMA_MAX_STATS_48
},
163 [IRDMA_HW_STAT_INDEX_IP4RXDISCARD
] = { 24, 0, IRDMA_MAX_STATS_32
},
164 [IRDMA_HW_STAT_INDEX_IP4RXTRUNC
] = { 32, 0, IRDMA_MAX_STATS_32
},
165 [IRDMA_HW_STAT_INDEX_IP4RXFRAGS
] = { 40, 0, IRDMA_MAX_STATS_48
},
166 [IRDMA_HW_STAT_INDEX_IP4RXMCPKTS
] = { 48, 0, IRDMA_MAX_STATS_48
},
167 [IRDMA_HW_STAT_INDEX_IP6RXOCTS
] = { 56, 0, IRDMA_MAX_STATS_48
},
168 [IRDMA_HW_STAT_INDEX_IP6RXPKTS
] = { 64, 0, IRDMA_MAX_STATS_48
},
169 [IRDMA_HW_STAT_INDEX_IP6RXDISCARD
] = { 72, 0, IRDMA_MAX_STATS_32
},
170 [IRDMA_HW_STAT_INDEX_IP6RXTRUNC
] = { 80, 0, IRDMA_MAX_STATS_32
},
171 [IRDMA_HW_STAT_INDEX_IP6RXFRAGS
] = { 88, 0, IRDMA_MAX_STATS_48
},
172 [IRDMA_HW_STAT_INDEX_IP6RXMCPKTS
] = { 96, 0, IRDMA_MAX_STATS_48
},
173 [IRDMA_HW_STAT_INDEX_IP4TXOCTS
] = { 104, 0, IRDMA_MAX_STATS_48
},
174 [IRDMA_HW_STAT_INDEX_IP4TXPKTS
] = { 112, 0, IRDMA_MAX_STATS_48
},
175 [IRDMA_HW_STAT_INDEX_IP4TXFRAGS
] = { 120, 0, IRDMA_MAX_STATS_48
},
176 [IRDMA_HW_STAT_INDEX_IP4TXMCPKTS
] = { 128, 0, IRDMA_MAX_STATS_48
},
177 [IRDMA_HW_STAT_INDEX_IP6TXOCTS
] = { 136, 0, IRDMA_MAX_STATS_48
},
178 [IRDMA_HW_STAT_INDEX_IP6TXPKTS
] = { 144, 0, IRDMA_MAX_STATS_48
},
179 [IRDMA_HW_STAT_INDEX_IP6TXFRAGS
] = { 152, 0, IRDMA_MAX_STATS_48
},
180 [IRDMA_HW_STAT_INDEX_IP6TXMCPKTS
] = { 160, 0, IRDMA_MAX_STATS_48
},
181 [IRDMA_HW_STAT_INDEX_IP4TXNOROUTE
] = { 168, 0, IRDMA_MAX_STATS_24
},
182 [IRDMA_HW_STAT_INDEX_IP6TXNOROUTE
] = { 176, 0, IRDMA_MAX_STATS_24
},
183 [IRDMA_HW_STAT_INDEX_TCPRXSEGS
] = { 184, 0, IRDMA_MAX_STATS_48
},
184 [IRDMA_HW_STAT_INDEX_TCPRXOPTERR
] = { 192, 0, IRDMA_MAX_STATS_24
},
185 [IRDMA_HW_STAT_INDEX_TCPRXPROTOERR
] = { 200, 0, IRDMA_MAX_STATS_24
},
186 [IRDMA_HW_STAT_INDEX_TCPTXSEG
] = { 208, 0, IRDMA_MAX_STATS_48
},
187 [IRDMA_HW_STAT_INDEX_TCPRTXSEG
] = { 216, 0, IRDMA_MAX_STATS_32
},
188 [IRDMA_HW_STAT_INDEX_RDMARXWRS
] = { 224, 0, IRDMA_MAX_STATS_48
},
189 [IRDMA_HW_STAT_INDEX_RDMARXRDS
] = { 232, 0, IRDMA_MAX_STATS_48
},
190 [IRDMA_HW_STAT_INDEX_RDMARXSNDS
] = { 240, 0, IRDMA_MAX_STATS_48
},
191 [IRDMA_HW_STAT_INDEX_RDMATXWRS
] = { 248, 0, IRDMA_MAX_STATS_48
},
192 [IRDMA_HW_STAT_INDEX_RDMATXRDS
] = { 256, 0, IRDMA_MAX_STATS_48
},
193 [IRDMA_HW_STAT_INDEX_RDMATXSNDS
] = { 264, 0, IRDMA_MAX_STATS_48
},
194 [IRDMA_HW_STAT_INDEX_RDMAVBND
] = { 272, 0, IRDMA_MAX_STATS_48
},
195 [IRDMA_HW_STAT_INDEX_RDMAVINV
] = { 280, 0, IRDMA_MAX_STATS_48
},
196 [IRDMA_HW_STAT_INDEX_IP4RXMCOCTS
] = { 288, 0, IRDMA_MAX_STATS_48
},
197 [IRDMA_HW_STAT_INDEX_IP4TXMCOCTS
] = { 296, 0, IRDMA_MAX_STATS_48
},
198 [IRDMA_HW_STAT_INDEX_IP6RXMCOCTS
] = { 304, 0, IRDMA_MAX_STATS_48
},
199 [IRDMA_HW_STAT_INDEX_IP6TXMCOCTS
] = { 312, 0, IRDMA_MAX_STATS_48
},
200 [IRDMA_HW_STAT_INDEX_UDPRXPKTS
] = { 320, 0, IRDMA_MAX_STATS_48
},
201 [IRDMA_HW_STAT_INDEX_UDPTXPKTS
] = { 328, 0, IRDMA_MAX_STATS_48
},
204 void i40iw_init_hw(struct irdma_sc_dev
*dev
)
209 for (i
= 0; i
< IRDMA_MAX_REGS
; ++i
) {
210 hw_addr
= dev
->hw
->hw_addr
;
212 if (i
== IRDMA_DB_ADDR_OFFSET
)
215 dev
->hw_regs
[i
] = (u32 __iomem
*)(i40iw_regs
[i
] + hw_addr
);
218 for (i
= 0; i
< IRDMA_HW_STAT_INDEX_MAX_GEN_1
; ++i
)
219 dev
->hw_stats_regs
[i
] = i40iw_stat_offsets
[i
];
221 dev
->hw_attrs
.first_hw_vf_fpm_id
= I40IW_FIRST_VF_FPM_ID
;
222 dev
->hw_attrs
.max_hw_vf_fpm_id
= IRDMA_MAX_VF_FPM_ID
;
224 for (i
= 0; i
< IRDMA_MAX_SHIFTS
; ++i
)
225 dev
->hw_shifts
[i
] = i40iw_shifts
[i
];
227 for (i
= 0; i
< IRDMA_MAX_MASKS
; ++i
)
228 dev
->hw_masks
[i
] = i40iw_masks
[i
];
230 dev
->wqe_alloc_db
= dev
->hw_regs
[IRDMA_WQEALLOC
];
231 dev
->cq_arm_db
= dev
->hw_regs
[IRDMA_CQARM
];
232 dev
->aeq_alloc_db
= dev
->hw_regs
[IRDMA_AEQALLOC
];
233 dev
->cqp_db
= dev
->hw_regs
[IRDMA_CQPDB
];
234 dev
->cq_ack_db
= dev
->hw_regs
[IRDMA_CQACK
];
235 dev
->ceq_itr_mask_db
= NULL
;
236 dev
->aeq_itr_mask_db
= NULL
;
237 dev
->irq_ops
= &i40iw_irq_ops
;
238 dev
->hw_stats_map
= i40iw_hw_stat_map
;
240 /* Setup the hardware limits, hmc may limit further */
241 dev
->hw_attrs
.uk_attrs
.max_hw_wq_frags
= I40IW_MAX_WQ_FRAGMENT_COUNT
;
242 dev
->hw_attrs
.uk_attrs
.max_hw_read_sges
= I40IW_MAX_SGE_RD
;
243 dev
->hw_attrs
.max_hw_device_pages
= I40IW_MAX_PUSH_PAGE_COUNT
;
244 dev
->hw_attrs
.uk_attrs
.max_hw_inline
= I40IW_MAX_INLINE_DATA_SIZE
;
245 dev
->hw_attrs
.page_size_cap
= SZ_4K
| SZ_2M
;
246 dev
->hw_attrs
.max_hw_ird
= I40IW_MAX_IRD_SIZE
;
247 dev
->hw_attrs
.max_hw_ord
= I40IW_MAX_ORD_SIZE
;
248 dev
->hw_attrs
.max_hw_wqes
= I40IW_MAX_WQ_ENTRIES
;
249 dev
->hw_attrs
.uk_attrs
.max_hw_rq_quanta
= I40IW_QP_SW_MAX_RQ_QUANTA
;
250 dev
->hw_attrs
.uk_attrs
.max_hw_wq_quanta
= I40IW_QP_SW_MAX_WQ_QUANTA
;
251 dev
->hw_attrs
.uk_attrs
.max_hw_sq_chunk
= I40IW_MAX_QUANTA_PER_WR
;
252 dev
->hw_attrs
.max_hw_pds
= I40IW_MAX_PDS
;
253 dev
->hw_attrs
.max_stat_inst
= I40IW_MAX_STATS_COUNT
;
254 dev
->hw_attrs
.max_stat_idx
= IRDMA_HW_STAT_INDEX_MAX_GEN_1
;
255 dev
->hw_attrs
.max_hw_outbound_msg_size
= I40IW_MAX_OUTBOUND_MSG_SIZE
;
256 dev
->hw_attrs
.max_hw_inbound_msg_size
= I40IW_MAX_INBOUND_MSG_SIZE
;
257 dev
->hw_attrs
.uk_attrs
.min_hw_wq_size
= I40IW_MIN_WQ_SIZE
;
258 dev
->hw_attrs
.max_qp_wr
= I40IW_MAX_QP_WRS
;