@@ -432,9 +432,92 @@ int bnxt_re_hwrm_qcaps(struct bnxt_re_dev *rdev)
432432 return rc ;
433433 cctx -> modes .db_push = le32_to_cpu (resp .flags ) & FUNC_QCAPS_RESP_FLAGS_WCB_PUSH_MODE ;
434434
435+ cctx -> modes .dbr_pacing =
436+ le32_to_cpu (resp .flags_ext2 ) & FUNC_QCAPS_RESP_FLAGS_EXT2_DBR_PACING_EXT_SUPPORTED ?
437+ true : false;
435438 return 0 ;
436439}
437440
441+ static int bnxt_re_hwrm_dbr_pacing_qcfg (struct bnxt_re_dev * rdev )
442+ {
443+ struct hwrm_func_dbr_pacing_qcfg_output resp = {};
444+ struct hwrm_func_dbr_pacing_qcfg_input req = {};
445+ struct bnxt_en_dev * en_dev = rdev -> en_dev ;
446+ struct bnxt_qplib_chip_ctx * cctx ;
447+ struct bnxt_fw_msg fw_msg = {};
448+ int rc ;
449+
450+ cctx = rdev -> chip_ctx ;
451+ bnxt_re_init_hwrm_hdr ((void * )& req , HWRM_FUNC_DBR_PACING_QCFG );
452+ bnxt_re_fill_fw_msg (& fw_msg , (void * )& req , sizeof (req ), (void * )& resp ,
453+ sizeof (resp ), DFLT_HWRM_CMD_TIMEOUT );
454+ rc = bnxt_send_msg (en_dev , & fw_msg );
455+ if (rc )
456+ return rc ;
457+
458+ if ((le32_to_cpu (resp .dbr_stat_db_fifo_reg ) &
459+ FUNC_DBR_PACING_QCFG_RESP_DBR_STAT_DB_FIFO_REG_ADDR_SPACE_MASK ) ==
460+ FUNC_DBR_PACING_QCFG_RESP_DBR_STAT_DB_FIFO_REG_ADDR_SPACE_GRC )
461+ cctx -> dbr_stat_db_fifo =
462+ le32_to_cpu (resp .dbr_stat_db_fifo_reg ) &
463+ ~FUNC_DBR_PACING_QCFG_RESP_DBR_STAT_DB_FIFO_REG_ADDR_SPACE_MASK ;
464+ return 0 ;
465+ }
466+
467+ /* Update the pacing tunable parameters to the default values */
468+ static void bnxt_re_set_default_pacing_data (struct bnxt_re_dev * rdev )
469+ {
470+ struct bnxt_qplib_db_pacing_data * pacing_data = rdev -> qplib_res .pacing_data ;
471+
472+ pacing_data -> do_pacing = rdev -> pacing .dbr_def_do_pacing ;
473+ pacing_data -> pacing_th = rdev -> pacing .pacing_algo_th ;
474+ pacing_data -> alarm_th =
475+ pacing_data -> pacing_th * BNXT_RE_PACING_ALARM_TH_MULTIPLE ;
476+ }
477+
478+ static int bnxt_re_initialize_dbr_pacing (struct bnxt_re_dev * rdev )
479+ {
480+ if (bnxt_re_hwrm_dbr_pacing_qcfg (rdev ))
481+ return - EIO ;
482+
483+ /* Allocate a page for app use */
484+ rdev -> pacing .dbr_page = (void * )__get_free_page (GFP_KERNEL );
485+ if (!rdev -> pacing .dbr_page )
486+ return - ENOMEM ;
487+
488+ memset ((u8 * )rdev -> pacing .dbr_page , 0 , PAGE_SIZE );
489+ rdev -> qplib_res .pacing_data = (struct bnxt_qplib_db_pacing_data * )rdev -> pacing .dbr_page ;
490+
491+ /* MAP HW window 2 for reading db fifo depth */
492+ writel (rdev -> chip_ctx -> dbr_stat_db_fifo & BNXT_GRC_BASE_MASK ,
493+ rdev -> en_dev -> bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4 );
494+ rdev -> pacing .dbr_db_fifo_reg_off =
495+ (rdev -> chip_ctx -> dbr_stat_db_fifo & BNXT_GRC_OFFSET_MASK ) +
496+ BNXT_RE_GRC_FIFO_REG_BASE ;
497+ rdev -> pacing .dbr_bar_addr =
498+ pci_resource_start (rdev -> qplib_res .pdev , 0 ) + rdev -> pacing .dbr_db_fifo_reg_off ;
499+
500+ rdev -> pacing .pacing_algo_th = BNXT_RE_PACING_ALGO_THRESHOLD ;
501+ rdev -> pacing .dbq_pacing_time = BNXT_RE_DBR_PACING_TIME ;
502+ rdev -> pacing .dbr_def_do_pacing = BNXT_RE_DBR_DO_PACING_NO_CONGESTION ;
503+ rdev -> pacing .do_pacing_save = rdev -> pacing .dbr_def_do_pacing ;
504+ rdev -> qplib_res .pacing_data -> fifo_max_depth = BNXT_RE_MAX_FIFO_DEPTH ;
505+ rdev -> qplib_res .pacing_data -> fifo_room_mask = BNXT_RE_DB_FIFO_ROOM_MASK ;
506+ rdev -> qplib_res .pacing_data -> fifo_room_shift = BNXT_RE_DB_FIFO_ROOM_SHIFT ;
507+ rdev -> qplib_res .pacing_data -> grc_reg_offset = rdev -> pacing .dbr_db_fifo_reg_off ;
508+ bnxt_re_set_default_pacing_data (rdev );
509+ return 0 ;
510+ }
511+
512+ static void bnxt_re_deinitialize_dbr_pacing (struct bnxt_re_dev * rdev )
513+ {
514+ if (rdev -> pacing .dbr_page )
515+ free_page ((u64 )rdev -> pacing .dbr_page );
516+
517+ rdev -> pacing .dbr_page = NULL ;
518+ rdev -> pacing .dbr_pacing = false;
519+ }
520+
438521static int bnxt_re_net_ring_free (struct bnxt_re_dev * rdev ,
439522 u16 fw_ring_id , int type )
440523{
@@ -1217,6 +1300,9 @@ static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev)
12171300 if (test_and_clear_bit (BNXT_RE_FLAG_GOT_MSIX , & rdev -> flags ))
12181301 rdev -> num_msix = 0 ;
12191302
1303+ if (rdev -> pacing .dbr_pacing )
1304+ bnxt_re_deinitialize_dbr_pacing (rdev );
1305+
12201306 bnxt_re_destroy_chip_ctx (rdev );
12211307 if (test_and_clear_bit (BNXT_RE_FLAG_NETDEV_REGISTERED , & rdev -> flags ))
12221308 bnxt_unregister_dev (rdev -> en_dev );
@@ -1309,6 +1395,16 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode)
13091395 goto free_ring ;
13101396 }
13111397
1398+ if (bnxt_qplib_dbr_pacing_en (rdev -> chip_ctx )) {
1399+ rc = bnxt_re_initialize_dbr_pacing (rdev );
1400+ if (!rc ) {
1401+ rdev -> pacing .dbr_pacing = true;
1402+ } else {
1403+ ibdev_err (& rdev -> ibdev ,
1404+ "DBR pacing disabled with error : %d\n" , rc );
1405+ rdev -> pacing .dbr_pacing = false;
1406+ }
1407+ }
13121408 rc = bnxt_qplib_get_dev_attr (& rdev -> rcfw , & rdev -> dev_attr ,
13131409 rdev -> is_virtfn );
13141410 if (rc )
0 commit comments