Skip to content

Commit 51ff172

Browse files
Ram Amranidavem330
authored andcommitted
qed: Add support for RoCE hw init
This adds the backbone required for the various HW initalizations which are necessary for the qedr driver - FW notification, resource initializations, etc. Signed-off-by: Ram Amrani <Ram.Amrani@caviumnetworks.com> Signed-off-by: Yuval Mintz <Yuval.Mintz@caviumnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent cee9fbd commit 51ff172

File tree

17 files changed

+1620
-8
lines changed

17 files changed

+1620
-8
lines changed

drivers/net/ethernet/qlogic/qed/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ qed-y := qed_cxt.o qed_dev.o qed_hw.o qed_init_fw_funcs.o qed_init_ops.o \
55
qed_selftest.o qed_dcbx.o qed_debug.o
66
qed-$(CONFIG_QED_SRIOV) += qed_sriov.o qed_vf.o
77
qed-$(CONFIG_QED_LL2) += qed_ll2.o
8+
qed-$(CONFIG_INFINIBAND_QEDR) += qed_roce.o

drivers/net/ethernet/qlogic/qed/qed.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ extern const struct qed_common_ops qed_common_ops_pass;
3535

3636
#define QED_WFQ_UNIT 100
3737

38+
#define QED_WID_SIZE (1024)
39+
#define QED_PF_DEMS_SIZE (4)
40+
3841
/* cau states */
3942
enum qed_coalescing_mode {
4043
QED_COAL_MODE_DISABLE,
@@ -48,6 +51,14 @@ enum qed_mcp_protocol_type;
4851

4952
/* helpers */
5053
static inline u32 qed_db_addr(u32 cid, u32 DEMS)
54+
{
55+
u32 db_addr = FIELD_VALUE(DB_LEGACY_ADDR_DEMS, DEMS) |
56+
(cid * QED_PF_DEMS_SIZE);
57+
58+
return db_addr;
59+
}
60+
61+
static inline u32 qed_db_addr_vf(u32 cid, u32 DEMS)
5162
{
5263
u32 db_addr = FIELD_VALUE(DB_LEGACY_ADDR_DEMS, DEMS) |
5364
FIELD_VALUE(DB_LEGACY_ADDR_ICID, cid);
@@ -152,14 +163,17 @@ enum QED_RESOURCES {
152163
QED_RL,
153164
QED_MAC,
154165
QED_VLAN,
166+
QED_RDMA_CNQ_RAM,
155167
QED_ILT,
156168
QED_LL2_QUEUE,
169+
QED_RDMA_STATS_QUEUE,
157170
QED_MAX_RESC,
158171
};
159172

160173
enum QED_FEATURE {
161174
QED_PF_L2_QUE,
162175
QED_VF,
176+
QED_RDMA_CNQ,
163177
QED_MAX_FEATURES,
164178
};
165179

@@ -364,6 +378,7 @@ struct qed_hwfn {
364378
/* Protocol related */
365379
bool using_ll2;
366380
struct qed_ll2_info *p_ll2_info;
381+
struct qed_rdma_info *p_rdma_info;
367382
struct qed_pf_params pf_params;
368383

369384
bool b_rdma_enabled_in_prs;
@@ -402,6 +417,17 @@ struct qed_hwfn {
402417

403418
struct dbg_tools_data dbg_info;
404419

420+
/* PWM region specific data */
421+
u32 dpi_size;
422+
u32 dpi_count;
423+
424+
/* This is used to calculate the doorbell address */
425+
u32 dpi_start_offset;
426+
427+
/* If one of the following is set then EDPM shouldn't be used */
428+
u8 dcbx_no_edpm;
429+
u8 db_bar_no_edpm;
430+
405431
struct qed_simd_fp_handler simd_proto_handler[64];
406432

407433
#ifdef CONFIG_QED_SRIOV
@@ -435,6 +461,8 @@ struct qed_int_params {
435461
bool fp_initialized;
436462
u8 fp_msix_base;
437463
u8 fp_msix_cnt;
464+
u8 rdma_msix_base;
465+
u8 rdma_msix_cnt;
438466
};
439467

440468
struct qed_dbg_feature {
@@ -541,7 +569,6 @@ struct qed_dev {
541569

542570
bool b_is_vf;
543571
u32 drv_type;
544-
545572
struct qed_eth_stats *reset_stats;
546573
struct qed_fw_data *fw_data;
547574

@@ -574,6 +601,10 @@ struct qed_dev {
574601
#endif
575602

576603
const struct firmware *firmware;
604+
605+
u32 rdma_max_sge;
606+
u32 rdma_max_inline;
607+
u32 rdma_max_srq_sge;
577608
};
578609

579610
#define NUM_OF_VFS(dev) MAX_NUM_VFS_BB

drivers/net/ethernet/qlogic/qed/qed_cxt.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,13 @@
4848
#define TM_ELEM_SIZE 4
4949

5050
/* ILT constants */
51+
#if IS_ENABLED(CONFIG_INFINIBAND_QEDR)
52+
/* For RoCE we configure to 64K to cover for RoCE max tasks 256K purpose. */
53+
#define ILT_DEFAULT_HW_P_SIZE 4
54+
#else
5155
#define ILT_DEFAULT_HW_P_SIZE 3
56+
#endif
57+
5258
#define ILT_PAGE_IN_BYTES(hw_p_size) (1U << ((hw_p_size) + 12))
5359
#define ILT_CFG_REG(cli, reg) PSWRQ2_REG_ ## cli ## _ ## reg ## _RT_OFFSET
5460

drivers/net/ethernet/qlogic/qed/qed_cxt.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,12 @@ int qed_qm_reconf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
170170
*/
171171
void qed_cxt_release_cid(struct qed_hwfn *p_hwfn,
172172
u32 cid);
173+
int qed_cxt_dynamic_ilt_alloc(struct qed_hwfn *p_hwfn,
174+
enum qed_cxt_elem_type elem_type, u32 iid);
175+
u32 qed_cxt_get_proto_tid_count(struct qed_hwfn *p_hwfn,
176+
enum protocol_type type);
177+
u32 qed_cxt_get_proto_cid_start(struct qed_hwfn *p_hwfn,
178+
enum protocol_type type);
173179

174180
#define QED_CTX_WORKING_MEM 0
175181
#define QED_CTX_FL_MEM 1

drivers/net/ethernet/qlogic/qed/qed_dev.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,13 @@
3535
#include "qed_sp.h"
3636
#include "qed_sriov.h"
3737
#include "qed_vf.h"
38+
#include "qed_roce.h"
3839

3940
static DEFINE_SPINLOCK(qm_lock);
4041

42+
#define QED_MIN_DPIS (4)
43+
#define QED_MIN_PWM_REGION (QED_WID_SIZE * QED_MIN_DPIS)
44+
4145
/* API common to all protocols */
4246
enum BAR_ID {
4347
BAR_ID_0, /* used for GRC */
@@ -787,6 +791,136 @@ static int qed_hw_init_common(struct qed_hwfn *p_hwfn,
787791
return rc;
788792
}
789793

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+
790924
static int qed_hw_init_port(struct qed_hwfn *p_hwfn,
791925
struct qed_ptt *p_ptt, int hw_mode)
792926
{
@@ -860,6 +994,10 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn,
860994
/* Pure runtime initializations - directly to the HW */
861995
qed_int_igu_init_pure_rt(p_hwfn, p_ptt, true, true);
862996

997+
rc = qed_hw_init_pf_doorbell_bar(p_hwfn, p_ptt);
998+
if (rc)
999+
return rc;
1000+
8631001
if (b_hw_start) {
8641002
/* enable interrupts */
8651003
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)
12841422
u32 *feat_num = p_hwfn->hw_info.feat_num;
12851423
int num_features = 1;
12861424

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
12871438
feat_num[QED_PF_L2_QUE] = min_t(u32, RESC_NUM(p_hwfn, QED_SB) /
12881439
num_features,
12891440
RESC_NUM(p_hwfn, QED_L2_QUEUE));
@@ -1325,6 +1476,9 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn)
13251476
num_funcs;
13261477
resc_num[QED_ILT] = PXP_NUM_ILT_RECORDS_BB / num_funcs;
13271478
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;
13281482

13291483
for (i = 0; i < QED_MAX_RESC; i++)
13301484
resc_start[i] = resc_num[i] * enabled_func_idx;

drivers/net/ethernet/qlogic/qed/qed_main.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
#include "qed_hw.h"
3434
#include "qed_selftest.h"
3535

36+
#if IS_ENABLED(CONFIG_INFINIBAND_QEDR)
37+
#define QED_ROCE_QPS (8192)
38+
#define QED_ROCE_DPIS (8)
39+
#endif
40+
3641
static char version[] =
3742
"QLogic FastLinQ 4xxxx Core Module qed " DRV_MODULE_VERSION "\n";
3843

@@ -206,8 +211,8 @@ int qed_fill_dev_info(struct qed_dev *cdev,
206211
dev_info->pci_mem_start = cdev->pci_params.mem_start;
207212
dev_info->pci_mem_end = cdev->pci_params.mem_end;
208213
dev_info->pci_irq = cdev->pci_params.irq;
209-
dev_info->rdma_supported =
210-
(cdev->hwfns[0].hw_info.personality == QED_PCI_ETH_ROCE);
214+
dev_info->rdma_supported = (cdev->hwfns[0].hw_info.personality ==
215+
QED_PCI_ETH_ROCE);
211216
dev_info->is_mf_default = IS_MF_DEFAULT(&cdev->hwfns[0]);
212217
ether_addr_copy(dev_info->hw_mac, cdev->hwfns[0].hw_info.hw_mac_addr);
213218

@@ -677,6 +682,9 @@ static int qed_slowpath_setup_int(struct qed_dev *cdev,
677682
enum qed_int_mode int_mode)
678683
{
679684
struct qed_sb_cnt_info sb_cnt_info;
685+
#if IS_ENABLED(CONFIG_INFINIBAND_QEDR)
686+
int num_l2_queues;
687+
#endif
680688
int rc;
681689
int i;
682690

@@ -707,6 +715,31 @@ static int qed_slowpath_setup_int(struct qed_dev *cdev,
707715
cdev->int_params.fp_msix_cnt = cdev->int_params.out.num_vectors -
708716
cdev->num_hwfns;
709717

718+
#if IS_ENABLED(CONFIG_INFINIBAND_QEDR)
719+
num_l2_queues = 0;
720+
for_each_hwfn(cdev, i)
721+
num_l2_queues += FEAT_NUM(&cdev->hwfns[i], QED_PF_L2_QUE);
722+
723+
DP_VERBOSE(cdev, QED_MSG_RDMA,
724+
"cdev->int_params.fp_msix_cnt=%d num_l2_queues=%d\n",
725+
cdev->int_params.fp_msix_cnt, num_l2_queues);
726+
727+
if (cdev->int_params.fp_msix_cnt > num_l2_queues) {
728+
cdev->int_params.rdma_msix_cnt =
729+
(cdev->int_params.fp_msix_cnt - num_l2_queues)
730+
/ cdev->num_hwfns;
731+
cdev->int_params.rdma_msix_base =
732+
cdev->int_params.fp_msix_base + num_l2_queues;
733+
cdev->int_params.fp_msix_cnt = num_l2_queues;
734+
} else {
735+
cdev->int_params.rdma_msix_cnt = 0;
736+
}
737+
738+
DP_VERBOSE(cdev, QED_MSG_RDMA, "roce_msix_cnt=%d roce_msix_base=%d\n",
739+
cdev->int_params.rdma_msix_cnt,
740+
cdev->int_params.rdma_msix_base);
741+
#endif
742+
710743
return 0;
711744
}
712745

@@ -810,6 +843,13 @@ static void qed_update_pf_params(struct qed_dev *cdev,
810843
{
811844
int i;
812845

846+
#if IS_ENABLED(CONFIG_INFINIBAND_QEDR)
847+
params->rdma_pf_params.num_qps = QED_ROCE_QPS;
848+
params->rdma_pf_params.min_dpis = QED_ROCE_DPIS;
849+
/* divide by 3 the MRs to avoid MF ILT overflow */
850+
params->rdma_pf_params.num_mrs = RDMA_MAX_TIDS;
851+
params->rdma_pf_params.gl_pi = QED_ROCE_PROTOCOL_INDEX;
852+
#endif
813853
for (i = 0; i < cdev->num_hwfns; i++) {
814854
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
815855

0 commit comments

Comments
 (0)