|
35 | 35 | #include "qed_sp.h" |
36 | 36 | #include "qed_sriov.h" |
37 | 37 | #include "qed_vf.h" |
| 38 | +#include "qed_roce.h" |
38 | 39 |
|
39 | 40 | static DEFINE_SPINLOCK(qm_lock); |
40 | 41 |
|
| 42 | +#define QED_MIN_DPIS (4) |
| 43 | +#define QED_MIN_PWM_REGION (QED_WID_SIZE * QED_MIN_DPIS) |
| 44 | + |
41 | 45 | /* API common to all protocols */ |
42 | 46 | enum BAR_ID { |
43 | 47 | BAR_ID_0, /* used for GRC */ |
@@ -787,6 +791,136 @@ static int qed_hw_init_common(struct qed_hwfn *p_hwfn, |
787 | 791 | return rc; |
788 | 792 | } |
789 | 793 |
|
| 794 | +static int |
| 795 | +qed_hw_init_dpi_size(struct qed_hwfn *p_hwfn, |
| 796 | + struct qed_ptt *p_ptt, u32 pwm_region_size, u32 n_cpus) |
| 797 | +{ |
| 798 | + u32 dpi_page_size_1, dpi_page_size_2, dpi_page_size; |
| 799 | + u32 dpi_bit_shift, dpi_count; |
| 800 | + u32 min_dpis; |
| 801 | + |
| 802 | + /* Calculate DPI size */ |
| 803 | + dpi_page_size_1 = QED_WID_SIZE * n_cpus; |
| 804 | + dpi_page_size_2 = max_t(u32, QED_WID_SIZE, PAGE_SIZE); |
| 805 | + dpi_page_size = max_t(u32, dpi_page_size_1, dpi_page_size_2); |
| 806 | + dpi_page_size = roundup_pow_of_two(dpi_page_size); |
| 807 | + dpi_bit_shift = ilog2(dpi_page_size / 4096); |
| 808 | + |
| 809 | + dpi_count = pwm_region_size / dpi_page_size; |
| 810 | + |
| 811 | + min_dpis = p_hwfn->pf_params.rdma_pf_params.min_dpis; |
| 812 | + min_dpis = max_t(u32, QED_MIN_DPIS, min_dpis); |
| 813 | + |
| 814 | + p_hwfn->dpi_size = dpi_page_size; |
| 815 | + p_hwfn->dpi_count = dpi_count; |
| 816 | + |
| 817 | + qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_DPI_BIT_SHIFT, dpi_bit_shift); |
| 818 | + |
| 819 | + if (dpi_count < min_dpis) |
| 820 | + return -EINVAL; |
| 821 | + |
| 822 | + return 0; |
| 823 | +} |
| 824 | + |
| 825 | +enum QED_ROCE_EDPM_MODE { |
| 826 | + QED_ROCE_EDPM_MODE_ENABLE = 0, |
| 827 | + QED_ROCE_EDPM_MODE_FORCE_ON = 1, |
| 828 | + QED_ROCE_EDPM_MODE_DISABLE = 2, |
| 829 | +}; |
| 830 | + |
| 831 | +static int |
| 832 | +qed_hw_init_pf_doorbell_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) |
| 833 | +{ |
| 834 | + u32 pwm_regsize, norm_regsize; |
| 835 | + u32 non_pwm_conn, min_addr_reg1; |
| 836 | + u32 db_bar_size, n_cpus; |
| 837 | + u32 roce_edpm_mode; |
| 838 | + u32 pf_dems_shift; |
| 839 | + int rc = 0; |
| 840 | + u8 cond; |
| 841 | + |
| 842 | + db_bar_size = qed_hw_bar_size(p_hwfn, BAR_ID_1); |
| 843 | + if (p_hwfn->cdev->num_hwfns > 1) |
| 844 | + db_bar_size /= 2; |
| 845 | + |
| 846 | + /* Calculate doorbell regions */ |
| 847 | + non_pwm_conn = qed_cxt_get_proto_cid_start(p_hwfn, PROTOCOLID_CORE) + |
| 848 | + qed_cxt_get_proto_cid_count(p_hwfn, PROTOCOLID_CORE, |
| 849 | + NULL) + |
| 850 | + qed_cxt_get_proto_cid_count(p_hwfn, PROTOCOLID_ETH, |
| 851 | + NULL); |
| 852 | + norm_regsize = roundup(QED_PF_DEMS_SIZE * non_pwm_conn, 4096); |
| 853 | + min_addr_reg1 = norm_regsize / 4096; |
| 854 | + pwm_regsize = db_bar_size - norm_regsize; |
| 855 | + |
| 856 | + /* Check that the normal and PWM sizes are valid */ |
| 857 | + if (db_bar_size < norm_regsize) { |
| 858 | + DP_ERR(p_hwfn->cdev, |
| 859 | + "Doorbell BAR size 0x%x is too small (normal region is 0x%0x )\n", |
| 860 | + db_bar_size, norm_regsize); |
| 861 | + return -EINVAL; |
| 862 | + } |
| 863 | + |
| 864 | + if (pwm_regsize < QED_MIN_PWM_REGION) { |
| 865 | + DP_ERR(p_hwfn->cdev, |
| 866 | + "PWM region size 0x%0x is too small. Should be at least 0x%0x (Doorbell BAR size is 0x%x and normal region size is 0x%0x)\n", |
| 867 | + pwm_regsize, |
| 868 | + QED_MIN_PWM_REGION, db_bar_size, norm_regsize); |
| 869 | + return -EINVAL; |
| 870 | + } |
| 871 | + |
| 872 | + /* Calculate number of DPIs */ |
| 873 | + roce_edpm_mode = p_hwfn->pf_params.rdma_pf_params.roce_edpm_mode; |
| 874 | + if ((roce_edpm_mode == QED_ROCE_EDPM_MODE_ENABLE) || |
| 875 | + ((roce_edpm_mode == QED_ROCE_EDPM_MODE_FORCE_ON))) { |
| 876 | + /* Either EDPM is mandatory, or we are attempting to allocate a |
| 877 | + * WID per CPU. |
| 878 | + */ |
| 879 | + n_cpus = num_active_cpus(); |
| 880 | + rc = qed_hw_init_dpi_size(p_hwfn, p_ptt, pwm_regsize, n_cpus); |
| 881 | + } |
| 882 | + |
| 883 | + cond = (rc && (roce_edpm_mode == QED_ROCE_EDPM_MODE_ENABLE)) || |
| 884 | + (roce_edpm_mode == QED_ROCE_EDPM_MODE_DISABLE); |
| 885 | + if (cond || p_hwfn->dcbx_no_edpm) { |
| 886 | + /* Either EDPM is disabled from user configuration, or it is |
| 887 | + * disabled via DCBx, or it is not mandatory and we failed to |
| 888 | + * allocated a WID per CPU. |
| 889 | + */ |
| 890 | + n_cpus = 1; |
| 891 | + rc = qed_hw_init_dpi_size(p_hwfn, p_ptt, pwm_regsize, n_cpus); |
| 892 | + |
| 893 | + if (cond) |
| 894 | + qed_rdma_dpm_bar(p_hwfn, p_ptt); |
| 895 | + } |
| 896 | + |
| 897 | + DP_INFO(p_hwfn, |
| 898 | + "doorbell bar: normal_region_size=%d, pwm_region_size=%d, dpi_size=%d, dpi_count=%d, roce_edpm=%s\n", |
| 899 | + norm_regsize, |
| 900 | + pwm_regsize, |
| 901 | + p_hwfn->dpi_size, |
| 902 | + p_hwfn->dpi_count, |
| 903 | + ((p_hwfn->dcbx_no_edpm) || (p_hwfn->db_bar_no_edpm)) ? |
| 904 | + "disabled" : "enabled"); |
| 905 | + |
| 906 | + if (rc) { |
| 907 | + DP_ERR(p_hwfn, |
| 908 | + "Failed to allocate enough DPIs. Allocated %d but the current minimum is %d.\n", |
| 909 | + p_hwfn->dpi_count, |
| 910 | + p_hwfn->pf_params.rdma_pf_params.min_dpis); |
| 911 | + return -EINVAL; |
| 912 | + } |
| 913 | + |
| 914 | + p_hwfn->dpi_start_offset = norm_regsize; |
| 915 | + |
| 916 | + /* DEMS size is configured log2 of DWORDs, hence the division by 4 */ |
| 917 | + pf_dems_shift = ilog2(QED_PF_DEMS_SIZE / 4); |
| 918 | + qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_ICID_BIT_SHIFT_NORM, pf_dems_shift); |
| 919 | + qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_MIN_ADDR_REG1, min_addr_reg1); |
| 920 | + |
| 921 | + return 0; |
| 922 | +} |
| 923 | + |
790 | 924 | static int qed_hw_init_port(struct qed_hwfn *p_hwfn, |
791 | 925 | struct qed_ptt *p_ptt, int hw_mode) |
792 | 926 | { |
@@ -860,6 +994,10 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn, |
860 | 994 | /* Pure runtime initializations - directly to the HW */ |
861 | 995 | qed_int_igu_init_pure_rt(p_hwfn, p_ptt, true, true); |
862 | 996 |
|
| 997 | + rc = qed_hw_init_pf_doorbell_bar(p_hwfn, p_ptt); |
| 998 | + if (rc) |
| 999 | + return rc; |
| 1000 | + |
863 | 1001 | if (b_hw_start) { |
864 | 1002 | /* enable interrupts */ |
865 | 1003 | qed_int_igu_enable(p_hwfn, p_ptt, int_mode); |
@@ -1284,6 +1422,19 @@ static void qed_hw_set_feat(struct qed_hwfn *p_hwfn) |
1284 | 1422 | u32 *feat_num = p_hwfn->hw_info.feat_num; |
1285 | 1423 | int num_features = 1; |
1286 | 1424 |
|
| 1425 | +#if IS_ENABLED(CONFIG_INFINIBAND_QEDR) |
| 1426 | + /* Roce CNQ each requires: 1 status block + 1 CNQ. We divide the |
| 1427 | + * status blocks equally between L2 / RoCE but with consideration as |
| 1428 | + * to how many l2 queues / cnqs we have |
| 1429 | + */ |
| 1430 | + if (p_hwfn->hw_info.personality == QED_PCI_ETH_ROCE) { |
| 1431 | + num_features++; |
| 1432 | + |
| 1433 | + feat_num[QED_RDMA_CNQ] = |
| 1434 | + min_t(u32, RESC_NUM(p_hwfn, QED_SB) / num_features, |
| 1435 | + RESC_NUM(p_hwfn, QED_RDMA_CNQ_RAM)); |
| 1436 | + } |
| 1437 | +#endif |
1287 | 1438 | feat_num[QED_PF_L2_QUE] = min_t(u32, RESC_NUM(p_hwfn, QED_SB) / |
1288 | 1439 | num_features, |
1289 | 1440 | RESC_NUM(p_hwfn, QED_L2_QUEUE)); |
@@ -1325,6 +1476,9 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn) |
1325 | 1476 | num_funcs; |
1326 | 1477 | resc_num[QED_ILT] = PXP_NUM_ILT_RECORDS_BB / num_funcs; |
1327 | 1478 | resc_num[QED_LL2_QUEUE] = MAX_NUM_LL2_RX_QUEUES / num_funcs; |
| 1479 | + resc_num[QED_RDMA_CNQ_RAM] = NUM_OF_CMDQS_CQS / num_funcs; |
| 1480 | + resc_num[QED_RDMA_STATS_QUEUE] = RDMA_NUM_STATISTIC_COUNTERS_BB / |
| 1481 | + num_funcs; |
1328 | 1482 |
|
1329 | 1483 | for (i = 0; i < QED_MAX_RESC; i++) |
1330 | 1484 | resc_start[i] = resc_num[i] * enabled_func_idx; |
|
0 commit comments