.. | .. |
---|
| 1 | +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) |
---|
1 | 2 | /* QLogic qed NIC Driver |
---|
2 | 3 | * Copyright (c) 2015-2017 QLogic Corporation |
---|
3 | | - * |
---|
4 | | - * This software is available to you under a choice of one of two |
---|
5 | | - * licenses. You may choose to be licensed under the terms of the GNU |
---|
6 | | - * General Public License (GPL) Version 2, available from the file |
---|
7 | | - * COPYING in the main directory of this source tree, or the |
---|
8 | | - * OpenIB.org BSD license below: |
---|
9 | | - * |
---|
10 | | - * Redistribution and use in source and binary forms, with or |
---|
11 | | - * without modification, are permitted provided that the following |
---|
12 | | - * conditions are met: |
---|
13 | | - * |
---|
14 | | - * - Redistributions of source code must retain the above |
---|
15 | | - * copyright notice, this list of conditions and the following |
---|
16 | | - * disclaimer. |
---|
17 | | - * |
---|
18 | | - * - Redistributions in binary form must reproduce the above |
---|
19 | | - * copyright notice, this list of conditions and the following |
---|
20 | | - * disclaimer in the documentation and /or other materials |
---|
21 | | - * provided with the distribution. |
---|
22 | | - * |
---|
23 | | - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
---|
24 | | - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
---|
25 | | - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
---|
26 | | - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
---|
27 | | - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
---|
28 | | - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
---|
29 | | - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
---|
30 | | - * SOFTWARE. |
---|
| 4 | + * Copyright (c) 2019-2020 Marvell International Ltd. |
---|
31 | 5 | */ |
---|
32 | 6 | |
---|
33 | 7 | #include <linux/types.h> |
---|
.. | .. |
---|
96 | 70 | #define ATTENTION_BB(value) (value << ATTENTION_BB_SHIFT) |
---|
97 | 71 | #define ATTENTION_BB_DIFFERENT BIT(23) |
---|
98 | 72 | |
---|
| 73 | +#define ATTENTION_CLEAR_ENABLE BIT(28) |
---|
99 | 74 | unsigned int flags; |
---|
100 | 75 | |
---|
101 | 76 | /* Callback to call if attention will be triggered */ |
---|
.. | .. |
---|
255 | 230 | #define PGLUE_ATTENTION_ICPL_VALID (1 << 23) |
---|
256 | 231 | #define PGLUE_ATTENTION_ZLR_VALID (1 << 25) |
---|
257 | 232 | #define PGLUE_ATTENTION_ILT_VALID (1 << 23) |
---|
258 | | -static int qed_pglub_rbc_attn_cb(struct qed_hwfn *p_hwfn) |
---|
| 233 | + |
---|
| 234 | +int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, |
---|
| 235 | + bool hw_init) |
---|
259 | 236 | { |
---|
| 237 | + char msg[256]; |
---|
260 | 238 | u32 tmp; |
---|
261 | 239 | |
---|
262 | | - tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
263 | | - PGLUE_B_REG_TX_ERR_WR_DETAILS2); |
---|
| 240 | + tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS2); |
---|
264 | 241 | if (tmp & PGLUE_ATTENTION_VALID) { |
---|
265 | 242 | u32 addr_lo, addr_hi, details; |
---|
266 | 243 | |
---|
267 | | - addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 244 | + addr_lo = qed_rd(p_hwfn, p_ptt, |
---|
268 | 245 | PGLUE_B_REG_TX_ERR_WR_ADD_31_0); |
---|
269 | | - addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 246 | + addr_hi = qed_rd(p_hwfn, p_ptt, |
---|
270 | 247 | PGLUE_B_REG_TX_ERR_WR_ADD_63_32); |
---|
271 | | - details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 248 | + details = qed_rd(p_hwfn, p_ptt, |
---|
272 | 249 | PGLUE_B_REG_TX_ERR_WR_DETAILS); |
---|
273 | 250 | |
---|
274 | | - DP_INFO(p_hwfn, |
---|
275 | | - "Illegal write by chip to [%08x:%08x] blocked.\n" |
---|
276 | | - "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n" |
---|
277 | | - "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n", |
---|
278 | | - addr_hi, addr_lo, details, |
---|
279 | | - (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID), |
---|
280 | | - (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID), |
---|
281 | | - GET_FIELD(details, |
---|
282 | | - PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0, |
---|
283 | | - tmp, |
---|
284 | | - GET_FIELD(tmp, |
---|
285 | | - PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1 : 0, |
---|
286 | | - GET_FIELD(tmp, |
---|
287 | | - PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0, |
---|
288 | | - GET_FIELD(tmp, |
---|
289 | | - PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1 : 0); |
---|
| 251 | + snprintf(msg, sizeof(msg), |
---|
| 252 | + "Illegal write by chip to [%08x:%08x] blocked.\n" |
---|
| 253 | + "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n" |
---|
| 254 | + "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]", |
---|
| 255 | + addr_hi, addr_lo, details, |
---|
| 256 | + (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID), |
---|
| 257 | + (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID), |
---|
| 258 | + !!GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VF_VALID), |
---|
| 259 | + tmp, |
---|
| 260 | + !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_WAS_ERR), |
---|
| 261 | + !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_BME), |
---|
| 262 | + !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_FID_EN)); |
---|
| 263 | + |
---|
| 264 | + if (hw_init) |
---|
| 265 | + DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, "%s\n", msg); |
---|
| 266 | + else |
---|
| 267 | + DP_NOTICE(p_hwfn, "%s\n", msg); |
---|
290 | 268 | } |
---|
291 | 269 | |
---|
292 | | - tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
293 | | - PGLUE_B_REG_TX_ERR_RD_DETAILS2); |
---|
| 270 | + tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_RD_DETAILS2); |
---|
294 | 271 | if (tmp & PGLUE_ATTENTION_RD_VALID) { |
---|
295 | 272 | u32 addr_lo, addr_hi, details; |
---|
296 | 273 | |
---|
297 | | - addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 274 | + addr_lo = qed_rd(p_hwfn, p_ptt, |
---|
298 | 275 | PGLUE_B_REG_TX_ERR_RD_ADD_31_0); |
---|
299 | | - addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 276 | + addr_hi = qed_rd(p_hwfn, p_ptt, |
---|
300 | 277 | PGLUE_B_REG_TX_ERR_RD_ADD_63_32); |
---|
301 | | - details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 278 | + details = qed_rd(p_hwfn, p_ptt, |
---|
302 | 279 | PGLUE_B_REG_TX_ERR_RD_DETAILS); |
---|
303 | 280 | |
---|
304 | | - DP_INFO(p_hwfn, |
---|
305 | | - "Illegal read by chip from [%08x:%08x] blocked.\n" |
---|
306 | | - " Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n" |
---|
307 | | - " Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n", |
---|
308 | | - addr_hi, addr_lo, details, |
---|
309 | | - (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID), |
---|
310 | | - (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID), |
---|
311 | | - GET_FIELD(details, |
---|
312 | | - PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0, |
---|
313 | | - tmp, |
---|
314 | | - GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1 |
---|
315 | | - : 0, |
---|
316 | | - GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0, |
---|
317 | | - GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1 |
---|
318 | | - : 0); |
---|
| 281 | + DP_NOTICE(p_hwfn, |
---|
| 282 | + "Illegal read by chip from [%08x:%08x] blocked.\n" |
---|
| 283 | + "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n" |
---|
| 284 | + "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n", |
---|
| 285 | + addr_hi, addr_lo, details, |
---|
| 286 | + (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID), |
---|
| 287 | + (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID), |
---|
| 288 | + GET_FIELD(details, |
---|
| 289 | + PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0, |
---|
| 290 | + tmp, |
---|
| 291 | + GET_FIELD(tmp, |
---|
| 292 | + PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1 : 0, |
---|
| 293 | + GET_FIELD(tmp, |
---|
| 294 | + PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0, |
---|
| 295 | + GET_FIELD(tmp, |
---|
| 296 | + PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1 : 0); |
---|
319 | 297 | } |
---|
320 | 298 | |
---|
321 | | - tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
322 | | - PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL); |
---|
323 | | - if (tmp & PGLUE_ATTENTION_ICPL_VALID) |
---|
324 | | - DP_INFO(p_hwfn, "ICPL error - %08x\n", tmp); |
---|
| 299 | + tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL); |
---|
| 300 | + if (tmp & PGLUE_ATTENTION_ICPL_VALID) { |
---|
| 301 | + snprintf(msg, sizeof(msg), "ICPL error - %08x", tmp); |
---|
325 | 302 | |
---|
326 | | - tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
327 | | - PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS); |
---|
| 303 | + if (hw_init) |
---|
| 304 | + DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, "%s\n", msg); |
---|
| 305 | + else |
---|
| 306 | + DP_NOTICE(p_hwfn, "%s\n", msg); |
---|
| 307 | + } |
---|
| 308 | + |
---|
| 309 | + tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS); |
---|
328 | 310 | if (tmp & PGLUE_ATTENTION_ZLR_VALID) { |
---|
329 | 311 | u32 addr_hi, addr_lo; |
---|
330 | 312 | |
---|
331 | | - addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 313 | + addr_lo = qed_rd(p_hwfn, p_ptt, |
---|
332 | 314 | PGLUE_B_REG_MASTER_ZLR_ERR_ADD_31_0); |
---|
333 | | - addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 315 | + addr_hi = qed_rd(p_hwfn, p_ptt, |
---|
334 | 316 | PGLUE_B_REG_MASTER_ZLR_ERR_ADD_63_32); |
---|
335 | 317 | |
---|
336 | | - DP_INFO(p_hwfn, "ZLR eror - %08x [Address %08x:%08x]\n", |
---|
337 | | - tmp, addr_hi, addr_lo); |
---|
| 318 | + DP_NOTICE(p_hwfn, "ZLR error - %08x [Address %08x:%08x]\n", |
---|
| 319 | + tmp, addr_hi, addr_lo); |
---|
338 | 320 | } |
---|
339 | 321 | |
---|
340 | | - tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
341 | | - PGLUE_B_REG_VF_ILT_ERR_DETAILS2); |
---|
| 322 | + tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_VF_ILT_ERR_DETAILS2); |
---|
342 | 323 | if (tmp & PGLUE_ATTENTION_ILT_VALID) { |
---|
343 | 324 | u32 addr_hi, addr_lo, details; |
---|
344 | 325 | |
---|
345 | | - addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 326 | + addr_lo = qed_rd(p_hwfn, p_ptt, |
---|
346 | 327 | PGLUE_B_REG_VF_ILT_ERR_ADD_31_0); |
---|
347 | | - addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 328 | + addr_hi = qed_rd(p_hwfn, p_ptt, |
---|
348 | 329 | PGLUE_B_REG_VF_ILT_ERR_ADD_63_32); |
---|
349 | | - details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
| 330 | + details = qed_rd(p_hwfn, p_ptt, |
---|
350 | 331 | PGLUE_B_REG_VF_ILT_ERR_DETAILS); |
---|
351 | 332 | |
---|
352 | | - DP_INFO(p_hwfn, |
---|
353 | | - "ILT error - Details %08x Details2 %08x [Address %08x:%08x]\n", |
---|
354 | | - details, tmp, addr_hi, addr_lo); |
---|
| 333 | + DP_NOTICE(p_hwfn, |
---|
| 334 | + "ILT error - Details %08x Details2 %08x [Address %08x:%08x]\n", |
---|
| 335 | + details, tmp, addr_hi, addr_lo); |
---|
355 | 336 | } |
---|
356 | 337 | |
---|
357 | 338 | /* Clear the indications */ |
---|
358 | | - qed_wr(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
359 | | - PGLUE_B_REG_LATCHED_ERRORS_CLR, (1 << 2)); |
---|
| 339 | + qed_wr(p_hwfn, p_ptt, PGLUE_B_REG_LATCHED_ERRORS_CLR, BIT(2)); |
---|
360 | 340 | |
---|
361 | 341 | return 0; |
---|
362 | 342 | } |
---|
363 | 343 | |
---|
364 | | -#define QED_DORQ_ATTENTION_REASON_MASK (0xfffff) |
---|
365 | | -#define QED_DORQ_ATTENTION_OPAQUE_MASK (0xffff) |
---|
366 | | -#define QED_DORQ_ATTENTION_SIZE_MASK (0x7f) |
---|
367 | | -#define QED_DORQ_ATTENTION_SIZE_SHIFT (16) |
---|
368 | | -static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn) |
---|
| 344 | +static int qed_pglueb_rbc_attn_cb(struct qed_hwfn *p_hwfn) |
---|
369 | 345 | { |
---|
370 | | - u32 reason; |
---|
| 346 | + return qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_dpc_ptt, false); |
---|
| 347 | +} |
---|
371 | 348 | |
---|
372 | | - reason = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, DORQ_REG_DB_DROP_REASON) & |
---|
373 | | - QED_DORQ_ATTENTION_REASON_MASK; |
---|
374 | | - if (reason) { |
---|
375 | | - u32 details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
376 | | - DORQ_REG_DB_DROP_DETAILS); |
---|
377 | | - |
---|
378 | | - DP_INFO(p_hwfn->cdev, |
---|
379 | | - "DORQ db_drop: address 0x%08x Opaque FID 0x%04x Size [bytes] 0x%08x Reason: 0x%08x\n", |
---|
380 | | - qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, |
---|
381 | | - DORQ_REG_DB_DROP_DETAILS_ADDRESS), |
---|
382 | | - (u16)(details & QED_DORQ_ATTENTION_OPAQUE_MASK), |
---|
383 | | - GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4, |
---|
384 | | - reason); |
---|
385 | | - } |
---|
| 349 | +static int qed_fw_assertion(struct qed_hwfn *p_hwfn) |
---|
| 350 | +{ |
---|
| 351 | + qed_hw_err_notify(p_hwfn, p_hwfn->p_dpc_ptt, QED_HW_ERR_FW_ASSERT, |
---|
| 352 | + "FW assertion!\n"); |
---|
386 | 353 | |
---|
387 | 354 | return -EINVAL; |
---|
| 355 | +} |
---|
| 356 | + |
---|
| 357 | +static int qed_general_attention_35(struct qed_hwfn *p_hwfn) |
---|
| 358 | +{ |
---|
| 359 | + DP_INFO(p_hwfn, "General attention 35!\n"); |
---|
| 360 | + |
---|
| 361 | + return 0; |
---|
| 362 | +} |
---|
| 363 | + |
---|
| 364 | +#define QED_DORQ_ATTENTION_REASON_MASK (0xfffff) |
---|
| 365 | +#define QED_DORQ_ATTENTION_OPAQUE_MASK (0xffff) |
---|
| 366 | +#define QED_DORQ_ATTENTION_OPAQUE_SHIFT (0x0) |
---|
| 367 | +#define QED_DORQ_ATTENTION_SIZE_MASK (0x7f) |
---|
| 368 | +#define QED_DORQ_ATTENTION_SIZE_SHIFT (16) |
---|
| 369 | + |
---|
| 370 | +#define QED_DB_REC_COUNT 1000 |
---|
| 371 | +#define QED_DB_REC_INTERVAL 100 |
---|
| 372 | + |
---|
| 373 | +static int qed_db_rec_flush_queue(struct qed_hwfn *p_hwfn, |
---|
| 374 | + struct qed_ptt *p_ptt) |
---|
| 375 | +{ |
---|
| 376 | + u32 count = QED_DB_REC_COUNT; |
---|
| 377 | + u32 usage = 1; |
---|
| 378 | + |
---|
| 379 | + /* Flush any pending (e)dpms as they may never arrive */ |
---|
| 380 | + qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1); |
---|
| 381 | + |
---|
| 382 | + /* wait for usage to zero or count to run out. This is necessary since |
---|
| 383 | + * EDPM doorbell transactions can take multiple 64b cycles, and as such |
---|
| 384 | + * can "split" over the pci. Possibly, the doorbell drop can happen with |
---|
| 385 | + * half an EDPM in the queue and other half dropped. Another EDPM |
---|
| 386 | + * doorbell to the same address (from doorbell recovery mechanism or |
---|
| 387 | + * from the doorbelling entity) could have first half dropped and second |
---|
| 388 | + * half interpreted as continuation of the first. To prevent such |
---|
| 389 | + * malformed doorbells from reaching the device, flush the queue before |
---|
| 390 | + * releasing the overflow sticky indication. |
---|
| 391 | + */ |
---|
| 392 | + while (count-- && usage) { |
---|
| 393 | + usage = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_USAGE_CNT); |
---|
| 394 | + udelay(QED_DB_REC_INTERVAL); |
---|
| 395 | + } |
---|
| 396 | + |
---|
| 397 | + /* should have been depleted by now */ |
---|
| 398 | + if (usage) { |
---|
| 399 | + DP_NOTICE(p_hwfn->cdev, |
---|
| 400 | + "DB recovery: doorbell usage failed to zero after %d usec. usage was %x\n", |
---|
| 401 | + QED_DB_REC_INTERVAL * QED_DB_REC_COUNT, usage); |
---|
| 402 | + return -EBUSY; |
---|
| 403 | + } |
---|
| 404 | + |
---|
| 405 | + return 0; |
---|
| 406 | +} |
---|
| 407 | + |
---|
| 408 | +int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) |
---|
| 409 | +{ |
---|
| 410 | + u32 attn_ovfl, cur_ovfl; |
---|
| 411 | + int rc; |
---|
| 412 | + |
---|
| 413 | + attn_ovfl = test_and_clear_bit(QED_OVERFLOW_BIT, |
---|
| 414 | + &p_hwfn->db_recovery_info.overflow); |
---|
| 415 | + cur_ovfl = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY); |
---|
| 416 | + if (!cur_ovfl && !attn_ovfl) |
---|
| 417 | + return 0; |
---|
| 418 | + |
---|
| 419 | + DP_NOTICE(p_hwfn, "PF Overflow sticky: attn %u current %u\n", |
---|
| 420 | + attn_ovfl, cur_ovfl); |
---|
| 421 | + |
---|
| 422 | + if (cur_ovfl && !p_hwfn->db_bar_no_edpm) { |
---|
| 423 | + rc = qed_db_rec_flush_queue(p_hwfn, p_ptt); |
---|
| 424 | + if (rc) |
---|
| 425 | + return rc; |
---|
| 426 | + } |
---|
| 427 | + |
---|
| 428 | + /* Release overflow sticky indication (stop silently dropping everything) */ |
---|
| 429 | + qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0); |
---|
| 430 | + |
---|
| 431 | + /* Repeat all last doorbells (doorbell drop recovery) */ |
---|
| 432 | + qed_db_recovery_execute(p_hwfn); |
---|
| 433 | + |
---|
| 434 | + return 0; |
---|
| 435 | +} |
---|
| 436 | + |
---|
| 437 | +static void qed_dorq_attn_overflow(struct qed_hwfn *p_hwfn) |
---|
| 438 | +{ |
---|
| 439 | + struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt; |
---|
| 440 | + u32 overflow; |
---|
| 441 | + int rc; |
---|
| 442 | + |
---|
| 443 | + overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY); |
---|
| 444 | + if (!overflow) |
---|
| 445 | + goto out; |
---|
| 446 | + |
---|
| 447 | + /* Run PF doorbell recovery in next periodic handler */ |
---|
| 448 | + set_bit(QED_OVERFLOW_BIT, &p_hwfn->db_recovery_info.overflow); |
---|
| 449 | + |
---|
| 450 | + if (!p_hwfn->db_bar_no_edpm) { |
---|
| 451 | + rc = qed_db_rec_flush_queue(p_hwfn, p_ptt); |
---|
| 452 | + if (rc) |
---|
| 453 | + goto out; |
---|
| 454 | + } |
---|
| 455 | + |
---|
| 456 | + qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0); |
---|
| 457 | +out: |
---|
| 458 | + /* Schedule the handler even if overflow was not detected */ |
---|
| 459 | + qed_periodic_db_rec_start(p_hwfn); |
---|
| 460 | +} |
---|
| 461 | + |
---|
| 462 | +static int qed_dorq_attn_int_sts(struct qed_hwfn *p_hwfn) |
---|
| 463 | +{ |
---|
| 464 | + u32 int_sts, first_drop_reason, details, address, all_drops_reason; |
---|
| 465 | + struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt; |
---|
| 466 | + |
---|
| 467 | + /* int_sts may be zero since all PFs were interrupted for doorbell |
---|
| 468 | + * overflow but another one already handled it. Can abort here. If |
---|
| 469 | + * This PF also requires overflow recovery we will be interrupted again. |
---|
| 470 | + * The masked almost full indication may also be set. Ignoring. |
---|
| 471 | + */ |
---|
| 472 | + int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS); |
---|
| 473 | + if (!(int_sts & ~DORQ_REG_INT_STS_DORQ_FIFO_AFULL)) |
---|
| 474 | + return 0; |
---|
| 475 | + |
---|
| 476 | + DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts); |
---|
| 477 | + |
---|
| 478 | + /* check if db_drop or overflow happened */ |
---|
| 479 | + if (int_sts & (DORQ_REG_INT_STS_DB_DROP | |
---|
| 480 | + DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) { |
---|
| 481 | + /* Obtain data about db drop/overflow */ |
---|
| 482 | + first_drop_reason = qed_rd(p_hwfn, p_ptt, |
---|
| 483 | + DORQ_REG_DB_DROP_REASON) & |
---|
| 484 | + QED_DORQ_ATTENTION_REASON_MASK; |
---|
| 485 | + details = qed_rd(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS); |
---|
| 486 | + address = qed_rd(p_hwfn, p_ptt, |
---|
| 487 | + DORQ_REG_DB_DROP_DETAILS_ADDRESS); |
---|
| 488 | + all_drops_reason = qed_rd(p_hwfn, p_ptt, |
---|
| 489 | + DORQ_REG_DB_DROP_DETAILS_REASON); |
---|
| 490 | + |
---|
| 491 | + /* Log info */ |
---|
| 492 | + DP_NOTICE(p_hwfn->cdev, |
---|
| 493 | + "Doorbell drop occurred\n" |
---|
| 494 | + "Address\t\t0x%08x\t(second BAR address)\n" |
---|
| 495 | + "FID\t\t0x%04x\t\t(Opaque FID)\n" |
---|
| 496 | + "Size\t\t0x%04x\t\t(in bytes)\n" |
---|
| 497 | + "1st drop reason\t0x%08x\t(details on first drop since last handling)\n" |
---|
| 498 | + "Sticky reasons\t0x%08x\t(all drop reasons since last handling)\n", |
---|
| 499 | + address, |
---|
| 500 | + GET_FIELD(details, QED_DORQ_ATTENTION_OPAQUE), |
---|
| 501 | + GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4, |
---|
| 502 | + first_drop_reason, all_drops_reason); |
---|
| 503 | + |
---|
| 504 | + /* Clear the doorbell drop details and prepare for next drop */ |
---|
| 505 | + qed_wr(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS_REL, 0); |
---|
| 506 | + |
---|
| 507 | + /* Mark interrupt as handled (note: even if drop was due to a different |
---|
| 508 | + * reason than overflow we mark as handled) |
---|
| 509 | + */ |
---|
| 510 | + qed_wr(p_hwfn, |
---|
| 511 | + p_ptt, |
---|
| 512 | + DORQ_REG_INT_STS_WR, |
---|
| 513 | + DORQ_REG_INT_STS_DB_DROP | |
---|
| 514 | + DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR); |
---|
| 515 | + |
---|
| 516 | + /* If there are no indications other than drop indications, success */ |
---|
| 517 | + if ((int_sts & ~(DORQ_REG_INT_STS_DB_DROP | |
---|
| 518 | + DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR | |
---|
| 519 | + DORQ_REG_INT_STS_DORQ_FIFO_AFULL)) == 0) |
---|
| 520 | + return 0; |
---|
| 521 | + } |
---|
| 522 | + |
---|
| 523 | + /* Some other indication was present - non recoverable */ |
---|
| 524 | + DP_INFO(p_hwfn, "DORQ fatal attention\n"); |
---|
| 525 | + |
---|
| 526 | + return -EINVAL; |
---|
| 527 | +} |
---|
| 528 | + |
---|
| 529 | +static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn) |
---|
| 530 | +{ |
---|
| 531 | + p_hwfn->db_recovery_info.dorq_attn = true; |
---|
| 532 | + qed_dorq_attn_overflow(p_hwfn); |
---|
| 533 | + |
---|
| 534 | + return qed_dorq_attn_int_sts(p_hwfn); |
---|
| 535 | +} |
---|
| 536 | + |
---|
| 537 | +static void qed_dorq_attn_handler(struct qed_hwfn *p_hwfn) |
---|
| 538 | +{ |
---|
| 539 | + if (p_hwfn->db_recovery_info.dorq_attn) |
---|
| 540 | + goto out; |
---|
| 541 | + |
---|
| 542 | + /* Call DORQ callback if the attention was missed */ |
---|
| 543 | + qed_dorq_attn_cb(p_hwfn); |
---|
| 544 | +out: |
---|
| 545 | + p_hwfn->db_recovery_info.dorq_attn = false; |
---|
388 | 546 | } |
---|
389 | 547 | |
---|
390 | 548 | /* Instead of major changes to the data-structure, we have a some 'special' |
---|
.. | .. |
---|
422 | 580 | {"PGLUE misc_flr", ATTENTION_SINGLE, |
---|
423 | 581 | NULL, MAX_BLOCK_ID}, |
---|
424 | 582 | {"PGLUE B RBC", ATTENTION_PAR_INT, |
---|
425 | | - qed_pglub_rbc_attn_cb, BLOCK_PGLUE_B}, |
---|
| 583 | + qed_pglueb_rbc_attn_cb, BLOCK_PGLUE_B}, |
---|
426 | 584 | {"PGLUE misc_mctp", ATTENTION_SINGLE, |
---|
427 | 585 | NULL, MAX_BLOCK_ID}, |
---|
428 | 586 | {"Flash event", ATTENTION_SINGLE, NULL, MAX_BLOCK_ID}, |
---|
.. | .. |
---|
445 | 603 | |
---|
446 | 604 | { |
---|
447 | 605 | { /* After Invert 4 */ |
---|
448 | | - {"General Attention 32", ATTENTION_SINGLE, |
---|
449 | | - NULL, MAX_BLOCK_ID}, |
---|
| 606 | + {"General Attention 32", ATTENTION_SINGLE | |
---|
| 607 | + ATTENTION_CLEAR_ENABLE, qed_fw_assertion, |
---|
| 608 | + MAX_BLOCK_ID}, |
---|
450 | 609 | {"General Attention %d", |
---|
451 | 610 | (2 << ATTENTION_LENGTH_SHIFT) | |
---|
452 | 611 | (33 << ATTENTION_OFFSET_SHIFT), NULL, MAX_BLOCK_ID}, |
---|
453 | | - {"General Attention 35", ATTENTION_SINGLE, |
---|
454 | | - NULL, MAX_BLOCK_ID}, |
---|
| 612 | + {"General Attention 35", ATTENTION_SINGLE | |
---|
| 613 | + ATTENTION_CLEAR_ENABLE, qed_general_attention_35, |
---|
| 614 | + MAX_BLOCK_ID}, |
---|
455 | 615 | {"NWS Parity", |
---|
456 | 616 | ATTENTION_PAR | ATTENTION_BB_DIFFERENT | |
---|
457 | 617 | ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_0), |
---|
.. | .. |
---|
654 | 814 | { |
---|
655 | 815 | u16 rc = 0, index; |
---|
656 | 816 | |
---|
657 | | - /* Make certain HW write took affect */ |
---|
658 | | - mmiowb(); |
---|
659 | | - |
---|
660 | 817 | index = le16_to_cpu(p_sb_desc->sb_attn->sb_index); |
---|
661 | 818 | if (p_sb_desc->index != index) { |
---|
662 | 819 | p_sb_desc->index = index; |
---|
663 | 820 | rc = QED_SB_ATT_IDX; |
---|
664 | 821 | } |
---|
665 | 822 | |
---|
666 | | - /* Make certain we got a consistent view with HW */ |
---|
667 | | - mmiowb(); |
---|
668 | | - |
---|
669 | 823 | return rc; |
---|
670 | 824 | } |
---|
671 | 825 | |
---|
672 | 826 | /** |
---|
673 | | - * @brief qed_int_assertion - handles asserted attention bits |
---|
| 827 | + * qed_int_assertion() - Handle asserted attention bits. |
---|
674 | 828 | * |
---|
675 | | - * @param p_hwfn |
---|
676 | | - * @param asserted_bits newly asserted bits |
---|
677 | | - * @return int |
---|
| 829 | + * @p_hwfn: HW device data. |
---|
| 830 | + * @asserted_bits: Newly asserted bits. |
---|
| 831 | + * |
---|
| 832 | + * Return: Zero value. |
---|
678 | 833 | */ |
---|
679 | 834 | static int qed_int_assertion(struct qed_hwfn *p_hwfn, u16 asserted_bits) |
---|
680 | 835 | { |
---|
.. | .. |
---|
734 | 889 | } |
---|
735 | 890 | |
---|
736 | 891 | /** |
---|
737 | | - * @brief qed_int_deassertion_aeu_bit - handles the effects of a single |
---|
738 | | - * cause of the attention |
---|
| 892 | + * qed_int_deassertion_aeu_bit() - Handles the effects of a single |
---|
| 893 | + * cause of the attention. |
---|
739 | 894 | * |
---|
740 | | - * @param p_hwfn |
---|
741 | | - * @param p_aeu - descriptor of an AEU bit which caused the attention |
---|
742 | | - * @param aeu_en_reg - register offset of the AEU enable reg. which configured |
---|
743 | | - * this bit to this group. |
---|
744 | | - * @param bit_index - index of this bit in the aeu_en_reg |
---|
| 895 | + * @p_hwfn: HW device data. |
---|
| 896 | + * @p_aeu: Descriptor of an AEU bit which caused the attention. |
---|
| 897 | + * @aeu_en_reg: Register offset of the AEU enable reg. which configured |
---|
| 898 | + * this bit to this group. |
---|
| 899 | + * @p_bit_name: AEU bit description for logging purposes. |
---|
| 900 | + * @bitmask: Index of this bit in the aeu_en_reg. |
---|
745 | 901 | * |
---|
746 | | - * @return int |
---|
| 902 | + * Return: Zero on success, negative errno otherwise. |
---|
747 | 903 | */ |
---|
748 | 904 | static int |
---|
749 | 905 | qed_int_deassertion_aeu_bit(struct qed_hwfn *p_hwfn, |
---|
.. | .. |
---|
773 | 929 | qed_int_attn_print(p_hwfn, p_aeu->block_index, |
---|
774 | 930 | ATTN_TYPE_INTERRUPT, !b_fatal); |
---|
775 | 931 | |
---|
776 | | - |
---|
777 | | - /* If the attention is benign, no need to prevent it */ |
---|
778 | | - if (!rc) |
---|
| 932 | + /* Reach assertion if attention is fatal */ |
---|
| 933 | + if (b_fatal) |
---|
| 934 | + qed_hw_err_notify(p_hwfn, p_hwfn->p_dpc_ptt, QED_HW_ERR_HW_ATTN, |
---|
| 935 | + "`%s': Fatal attention\n", |
---|
| 936 | + p_bit_name); |
---|
| 937 | + else /* If the attention is benign, no need to prevent it */ |
---|
779 | 938 | goto out; |
---|
780 | 939 | |
---|
781 | 940 | /* Prevent this Attention from being asserted in the future */ |
---|
.. | .. |
---|
789 | 948 | } |
---|
790 | 949 | |
---|
791 | 950 | /** |
---|
792 | | - * @brief qed_int_deassertion_parity - handle a single parity AEU source |
---|
| 951 | + * qed_int_deassertion_parity() - Handle a single parity AEU source. |
---|
793 | 952 | * |
---|
794 | | - * @param p_hwfn |
---|
795 | | - * @param p_aeu - descriptor of an AEU bit which caused the parity |
---|
796 | | - * @param aeu_en_reg - address of the AEU enable register |
---|
797 | | - * @param bit_index |
---|
| 953 | + * @p_hwfn: HW device data. |
---|
| 954 | + * @p_aeu: Descriptor of an AEU bit which caused the parity. |
---|
| 955 | + * @aeu_en_reg: Address of the AEU enable register. |
---|
| 956 | + * @bit_index: Index (0-31) of an AEU bit. |
---|
798 | 957 | */ |
---|
799 | 958 | static void qed_int_deassertion_parity(struct qed_hwfn *p_hwfn, |
---|
800 | 959 | struct aeu_invert_reg_bit *p_aeu, |
---|
.. | .. |
---|
827 | 986 | } |
---|
828 | 987 | |
---|
829 | 988 | /** |
---|
830 | | - * @brief - handles deassertion of previously asserted attentions. |
---|
| 989 | + * qed_int_deassertion() - Handle deassertion of previously asserted |
---|
| 990 | + * attentions. |
---|
831 | 991 | * |
---|
832 | | - * @param p_hwfn |
---|
833 | | - * @param deasserted_bits - newly deasserted bits |
---|
834 | | - * @return int |
---|
| 992 | + * @p_hwfn: HW device data. |
---|
| 993 | + * @deasserted_bits: newly deasserted bits. |
---|
835 | 994 | * |
---|
| 995 | + * Return: Zero value. |
---|
836 | 996 | */ |
---|
837 | 997 | static int qed_int_deassertion(struct qed_hwfn *p_hwfn, |
---|
838 | 998 | u16 deasserted_bits) |
---|
.. | .. |
---|
960 | 1120 | } |
---|
961 | 1121 | } |
---|
962 | 1122 | |
---|
| 1123 | + /* Handle missed DORQ attention */ |
---|
| 1124 | + qed_dorq_attn_handler(p_hwfn); |
---|
| 1125 | + |
---|
963 | 1126 | /* Clear IGU indication for the deasserted bits */ |
---|
964 | 1127 | DIRECT_REG_WR((u8 __iomem *)p_hwfn->regview + |
---|
965 | 1128 | GTT_BAR0_MAP_REG_IGU_CMD + |
---|
.. | .. |
---|
1037 | 1200 | static void qed_sb_ack_attn(struct qed_hwfn *p_hwfn, |
---|
1038 | 1201 | void __iomem *igu_addr, u32 ack_cons) |
---|
1039 | 1202 | { |
---|
1040 | | - struct igu_prod_cons_update igu_ack = { 0 }; |
---|
| 1203 | + u32 igu_ack; |
---|
1041 | 1204 | |
---|
1042 | | - igu_ack.sb_id_and_flags = |
---|
1043 | | - ((ack_cons << IGU_PROD_CONS_UPDATE_SB_INDEX_SHIFT) | |
---|
1044 | | - (1 << IGU_PROD_CONS_UPDATE_UPDATE_FLAG_SHIFT) | |
---|
1045 | | - (IGU_INT_NOP << IGU_PROD_CONS_UPDATE_ENABLE_INT_SHIFT) | |
---|
1046 | | - (IGU_SEG_ACCESS_ATTN << |
---|
1047 | | - IGU_PROD_CONS_UPDATE_SEGMENT_ACCESS_SHIFT)); |
---|
| 1205 | + igu_ack = ((ack_cons << IGU_PROD_CONS_UPDATE_SB_INDEX_SHIFT) | |
---|
| 1206 | + (1 << IGU_PROD_CONS_UPDATE_UPDATE_FLAG_SHIFT) | |
---|
| 1207 | + (IGU_INT_NOP << IGU_PROD_CONS_UPDATE_ENABLE_INT_SHIFT) | |
---|
| 1208 | + (IGU_SEG_ACCESS_ATTN << |
---|
| 1209 | + IGU_PROD_CONS_UPDATE_SEGMENT_ACCESS_SHIFT)); |
---|
1048 | 1210 | |
---|
1049 | | - DIRECT_REG_WR(igu_addr, igu_ack.sb_id_and_flags); |
---|
| 1211 | + DIRECT_REG_WR(igu_addr, igu_ack); |
---|
1050 | 1212 | |
---|
1051 | 1213 | /* Both segments (interrupts & acks) are written to same place address; |
---|
1052 | 1214 | * Need to guarantee all commands will be received (in-order) by HW. |
---|
1053 | 1215 | */ |
---|
1054 | | - mmiowb(); |
---|
1055 | 1216 | barrier(); |
---|
1056 | 1217 | } |
---|
1057 | 1218 | |
---|
1058 | | -void qed_int_sp_dpc(unsigned long hwfn_cookie) |
---|
| 1219 | +void qed_int_sp_dpc(struct tasklet_struct *t) |
---|
1059 | 1220 | { |
---|
1060 | | - struct qed_hwfn *p_hwfn = (struct qed_hwfn *)hwfn_cookie; |
---|
| 1221 | + struct qed_hwfn *p_hwfn = from_tasklet(p_hwfn, t, sp_dpc); |
---|
1061 | 1222 | struct qed_pi_info *pi_info = NULL; |
---|
1062 | 1223 | struct qed_sb_attn_info *sb_attn; |
---|
1063 | 1224 | struct qed_sb_info *sb_info; |
---|
.. | .. |
---|
1261 | 1422 | u8 pf_id, u16 vf_number, u8 vf_valid) |
---|
1262 | 1423 | { |
---|
1263 | 1424 | struct qed_dev *cdev = p_hwfn->cdev; |
---|
1264 | | - u32 cau_state; |
---|
| 1425 | + u32 cau_state, params = 0, data = 0; |
---|
1265 | 1426 | u8 timer_res; |
---|
1266 | 1427 | |
---|
1267 | 1428 | memset(p_sb_entry, 0, sizeof(*p_sb_entry)); |
---|
1268 | 1429 | |
---|
1269 | | - SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_PF_NUMBER, pf_id); |
---|
1270 | | - SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_VF_NUMBER, vf_number); |
---|
1271 | | - SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_VF_VALID, vf_valid); |
---|
1272 | | - SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_SB_TIMESET0, 0x7F); |
---|
1273 | | - SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_SB_TIMESET1, 0x7F); |
---|
| 1430 | + SET_FIELD(params, CAU_SB_ENTRY_PF_NUMBER, pf_id); |
---|
| 1431 | + SET_FIELD(params, CAU_SB_ENTRY_VF_NUMBER, vf_number); |
---|
| 1432 | + SET_FIELD(params, CAU_SB_ENTRY_VF_VALID, vf_valid); |
---|
| 1433 | + SET_FIELD(params, CAU_SB_ENTRY_SB_TIMESET0, 0x7F); |
---|
| 1434 | + SET_FIELD(params, CAU_SB_ENTRY_SB_TIMESET1, 0x7F); |
---|
1274 | 1435 | |
---|
1275 | 1436 | cau_state = CAU_HC_DISABLE_STATE; |
---|
1276 | 1437 | |
---|
.. | .. |
---|
1289 | 1450 | timer_res = 1; |
---|
1290 | 1451 | else |
---|
1291 | 1452 | timer_res = 2; |
---|
1292 | | - SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_TIMER_RES0, timer_res); |
---|
| 1453 | + |
---|
| 1454 | + SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES0, timer_res); |
---|
1293 | 1455 | |
---|
1294 | 1456 | if (cdev->tx_coalesce_usecs <= 0x7F) |
---|
1295 | 1457 | timer_res = 0; |
---|
.. | .. |
---|
1297 | 1459 | timer_res = 1; |
---|
1298 | 1460 | else |
---|
1299 | 1461 | timer_res = 2; |
---|
1300 | | - SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_TIMER_RES1, timer_res); |
---|
1301 | 1462 | |
---|
1302 | | - SET_FIELD(p_sb_entry->data, CAU_SB_ENTRY_STATE0, cau_state); |
---|
1303 | | - SET_FIELD(p_sb_entry->data, CAU_SB_ENTRY_STATE1, cau_state); |
---|
| 1463 | + SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES1, timer_res); |
---|
| 1464 | + p_sb_entry->params = cpu_to_le32(params); |
---|
| 1465 | + |
---|
| 1466 | + SET_FIELD(data, CAU_SB_ENTRY_STATE0, cau_state); |
---|
| 1467 | + SET_FIELD(data, CAU_SB_ENTRY_STATE1, cau_state); |
---|
| 1468 | + p_sb_entry->data = cpu_to_le32(data); |
---|
1304 | 1469 | } |
---|
1305 | 1470 | |
---|
1306 | 1471 | static void qed_int_cau_conf_pi(struct qed_hwfn *p_hwfn, |
---|
.. | .. |
---|
1310 | 1475 | enum qed_coalescing_fsm coalescing_fsm, |
---|
1311 | 1476 | u8 timeset) |
---|
1312 | 1477 | { |
---|
1313 | | - struct cau_pi_entry pi_entry; |
---|
1314 | 1478 | u32 sb_offset, pi_offset; |
---|
| 1479 | + u32 prod = 0; |
---|
1315 | 1480 | |
---|
1316 | 1481 | if (IS_VF(p_hwfn->cdev)) |
---|
1317 | 1482 | return; |
---|
1318 | 1483 | |
---|
1319 | | - sb_offset = igu_sb_id * PIS_PER_SB_E4; |
---|
1320 | | - memset(&pi_entry, 0, sizeof(struct cau_pi_entry)); |
---|
1321 | | - |
---|
1322 | | - SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_PI_TIMESET, timeset); |
---|
| 1484 | + SET_FIELD(prod, CAU_PI_ENTRY_PI_TIMESET, timeset); |
---|
1323 | 1485 | if (coalescing_fsm == QED_COAL_RX_STATE_MACHINE) |
---|
1324 | | - SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 0); |
---|
| 1486 | + SET_FIELD(prod, CAU_PI_ENTRY_FSM_SEL, 0); |
---|
1325 | 1487 | else |
---|
1326 | | - SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 1); |
---|
| 1488 | + SET_FIELD(prod, CAU_PI_ENTRY_FSM_SEL, 1); |
---|
1327 | 1489 | |
---|
| 1490 | + sb_offset = igu_sb_id * PIS_PER_SB_E4; |
---|
1328 | 1491 | pi_offset = sb_offset + pi_index; |
---|
1329 | | - if (p_hwfn->hw_init_done) { |
---|
| 1492 | + |
---|
| 1493 | + if (p_hwfn->hw_init_done) |
---|
1330 | 1494 | qed_wr(p_hwfn, p_ptt, |
---|
1331 | | - CAU_REG_PI_MEMORY + pi_offset * sizeof(u32), |
---|
1332 | | - *((u32 *)&(pi_entry))); |
---|
1333 | | - } else { |
---|
1334 | | - STORE_RT_REG(p_hwfn, |
---|
1335 | | - CAU_REG_PI_MEMORY_RT_OFFSET + pi_offset, |
---|
1336 | | - *((u32 *)&(pi_entry))); |
---|
1337 | | - } |
---|
| 1495 | + CAU_REG_PI_MEMORY + pi_offset * sizeof(u32), prod); |
---|
| 1496 | + else |
---|
| 1497 | + STORE_RT_REG(p_hwfn, CAU_REG_PI_MEMORY_RT_OFFSET + pi_offset, |
---|
| 1498 | + prod); |
---|
1338 | 1499 | } |
---|
1339 | 1500 | |
---|
1340 | 1501 | void qed_int_cau_conf_sb(struct qed_hwfn *p_hwfn, |
---|
.. | .. |
---|
1353 | 1514 | |
---|
1354 | 1515 | qed_dmae_host2grc(p_hwfn, p_ptt, (u64)(uintptr_t)&phys_addr, |
---|
1355 | 1516 | CAU_REG_SB_ADDR_MEMORY + |
---|
1356 | | - igu_sb_id * sizeof(u64), 2, 0); |
---|
| 1517 | + igu_sb_id * sizeof(u64), 2, NULL); |
---|
1357 | 1518 | qed_dmae_host2grc(p_hwfn, p_ptt, (u64)(uintptr_t)&sb_entry, |
---|
1358 | 1519 | CAU_REG_SB_VAR_MEMORY + |
---|
1359 | | - igu_sb_id * sizeof(u64), 2, 0); |
---|
| 1520 | + igu_sb_id * sizeof(u64), 2, NULL); |
---|
1360 | 1521 | } else { |
---|
1361 | 1522 | /* Initialize Status Block Address */ |
---|
1362 | 1523 | STORE_RT_REG_AGG(p_hwfn, |
---|
.. | .. |
---|
1686 | 1847 | qed_wr(p_hwfn, p_ptt, IGU_REG_TRAILING_EDGE_LATCH, 0xfff); |
---|
1687 | 1848 | qed_wr(p_hwfn, p_ptt, IGU_REG_ATTENTION_ENABLE, 0xfff); |
---|
1688 | 1849 | |
---|
1689 | | - /* Flush the writes to IGU */ |
---|
1690 | | - mmiowb(); |
---|
1691 | | - |
---|
1692 | 1850 | /* Unmask AEU signals toward IGU */ |
---|
1693 | 1851 | qed_wr(p_hwfn, p_ptt, MISC_REG_AEU_MASK_ATTN_IGU, 0xff); |
---|
1694 | 1852 | } |
---|
.. | .. |
---|
1751 | 1909 | barrier(); |
---|
1752 | 1910 | |
---|
1753 | 1911 | qed_wr(p_hwfn, p_ptt, IGU_REG_COMMAND_REG_CTRL, cmd_ctrl); |
---|
1754 | | - |
---|
1755 | | - /* Flush the write to IGU */ |
---|
1756 | | - mmiowb(); |
---|
1757 | 1912 | |
---|
1758 | 1913 | /* calculate where to read the status bit from */ |
---|
1759 | 1914 | sb_bit = 1 << (igu_sb_id % 32); |
---|
.. | .. |
---|
2097 | 2252 | } |
---|
2098 | 2253 | |
---|
2099 | 2254 | /** |
---|
2100 | | - * @brief Initialize igu runtime registers |
---|
| 2255 | + * qed_int_igu_init_rt() - Initialize IGU runtime registers. |
---|
2101 | 2256 | * |
---|
2102 | | - * @param p_hwfn |
---|
| 2257 | + * @p_hwfn: HW device data. |
---|
2103 | 2258 | */ |
---|
2104 | 2259 | void qed_int_igu_init_rt(struct qed_hwfn *p_hwfn) |
---|
2105 | 2260 | { |
---|
.. | .. |
---|
2130 | 2285 | |
---|
2131 | 2286 | static void qed_int_sp_dpc_setup(struct qed_hwfn *p_hwfn) |
---|
2132 | 2287 | { |
---|
2133 | | - tasklet_init(p_hwfn->sp_dpc, |
---|
2134 | | - qed_int_sp_dpc, (unsigned long)p_hwfn); |
---|
| 2288 | + tasklet_setup(&p_hwfn->sp_dpc, qed_int_sp_dpc); |
---|
2135 | 2289 | p_hwfn->b_sp_dpc_enabled = true; |
---|
2136 | | -} |
---|
2137 | | - |
---|
2138 | | -static int qed_int_sp_dpc_alloc(struct qed_hwfn *p_hwfn) |
---|
2139 | | -{ |
---|
2140 | | - p_hwfn->sp_dpc = kmalloc(sizeof(*p_hwfn->sp_dpc), GFP_KERNEL); |
---|
2141 | | - if (!p_hwfn->sp_dpc) |
---|
2142 | | - return -ENOMEM; |
---|
2143 | | - |
---|
2144 | | - return 0; |
---|
2145 | | -} |
---|
2146 | | - |
---|
2147 | | -static void qed_int_sp_dpc_free(struct qed_hwfn *p_hwfn) |
---|
2148 | | -{ |
---|
2149 | | - kfree(p_hwfn->sp_dpc); |
---|
2150 | | - p_hwfn->sp_dpc = NULL; |
---|
2151 | 2290 | } |
---|
2152 | 2291 | |
---|
2153 | 2292 | int qed_int_alloc(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) |
---|
2154 | 2293 | { |
---|
2155 | 2294 | int rc = 0; |
---|
2156 | | - |
---|
2157 | | - rc = qed_int_sp_dpc_alloc(p_hwfn); |
---|
2158 | | - if (rc) |
---|
2159 | | - return rc; |
---|
2160 | 2295 | |
---|
2161 | 2296 | rc = qed_int_sp_sb_alloc(p_hwfn, p_ptt); |
---|
2162 | 2297 | if (rc) |
---|
.. | .. |
---|
2171 | 2306 | { |
---|
2172 | 2307 | qed_int_sp_sb_free(p_hwfn); |
---|
2173 | 2308 | qed_int_sb_attn_free(p_hwfn); |
---|
2174 | | - qed_int_sp_dpc_free(p_hwfn); |
---|
2175 | 2309 | } |
---|
2176 | 2310 | |
---|
2177 | 2311 | void qed_int_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) |
---|
.. | .. |
---|
2200 | 2334 | cdev->hwfns[i].b_int_requested = false; |
---|
2201 | 2335 | } |
---|
2202 | 2336 | |
---|
| 2337 | +void qed_int_attn_clr_enable(struct qed_dev *cdev, bool clr_enable) |
---|
| 2338 | +{ |
---|
| 2339 | + cdev->attn_clr_en = clr_enable; |
---|
| 2340 | +} |
---|
| 2341 | + |
---|
2203 | 2342 | int qed_int_set_timer_res(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, |
---|
2204 | 2343 | u8 timer_res, u16 sb_id, bool tx) |
---|
2205 | 2344 | { |
---|
2206 | 2345 | struct cau_sb_entry sb_entry; |
---|
| 2346 | + u32 params; |
---|
2207 | 2347 | int rc; |
---|
2208 | 2348 | |
---|
2209 | 2349 | if (!p_hwfn->hw_init_done) { |
---|
.. | .. |
---|
2213 | 2353 | |
---|
2214 | 2354 | rc = qed_dmae_grc2host(p_hwfn, p_ptt, CAU_REG_SB_VAR_MEMORY + |
---|
2215 | 2355 | sb_id * sizeof(u64), |
---|
2216 | | - (u64)(uintptr_t)&sb_entry, 2, 0); |
---|
| 2356 | + (u64)(uintptr_t)&sb_entry, 2, NULL); |
---|
2217 | 2357 | if (rc) { |
---|
2218 | 2358 | DP_ERR(p_hwfn, "dmae_grc2host failed %d\n", rc); |
---|
2219 | 2359 | return rc; |
---|
2220 | 2360 | } |
---|
2221 | 2361 | |
---|
| 2362 | + params = le32_to_cpu(sb_entry.params); |
---|
| 2363 | + |
---|
2222 | 2364 | if (tx) |
---|
2223 | | - SET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES1, timer_res); |
---|
| 2365 | + SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES1, timer_res); |
---|
2224 | 2366 | else |
---|
2225 | | - SET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES0, timer_res); |
---|
| 2367 | + SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES0, timer_res); |
---|
| 2368 | + |
---|
| 2369 | + sb_entry.params = cpu_to_le32(params); |
---|
2226 | 2370 | |
---|
2227 | 2371 | rc = qed_dmae_host2grc(p_hwfn, p_ptt, |
---|
2228 | 2372 | (u64)(uintptr_t)&sb_entry, |
---|
2229 | 2373 | CAU_REG_SB_VAR_MEMORY + |
---|
2230 | | - sb_id * sizeof(u64), 2, 0); |
---|
| 2374 | + sb_id * sizeof(u64), 2, NULL); |
---|
2231 | 2375 | if (rc) { |
---|
2232 | 2376 | DP_ERR(p_hwfn, "dmae_host2grc failed %d\n", rc); |
---|
2233 | 2377 | return rc; |
---|