0001
0002
0003 #include "osdep.h"
0004 #include "type.h"
0005 #include "icrdma_hw.h"
0006
0007 static u32 icrdma_regs[IRDMA_MAX_REGS] = {
0008 PFPE_CQPTAIL,
0009 PFPE_CQPDB,
0010 PFPE_CCQPSTATUS,
0011 PFPE_CCQPHIGH,
0012 PFPE_CCQPLOW,
0013 PFPE_CQARM,
0014 PFPE_CQACK,
0015 PFPE_AEQALLOC,
0016 PFPE_CQPERRCODES,
0017 PFPE_WQEALLOC,
0018 GLINT_DYN_CTL(0),
0019 ICRDMA_DB_ADDR_OFFSET,
0020
0021 GLPCI_LBARCTRL,
0022 GLPE_CPUSTATUS0,
0023 GLPE_CPUSTATUS1,
0024 GLPE_CPUSTATUS2,
0025 PFINT_AEQCTL,
0026 GLINT_CEQCTL(0),
0027 VSIQF_PE_CTL1(0),
0028 PFHMC_PDINV,
0029 GLHMC_VFPDINV(0),
0030 GLPE_CRITERR,
0031 GLINT_RATE(0),
0032 };
0033
0034 static u64 icrdma_masks[IRDMA_MAX_MASKS] = {
0035 ICRDMA_CCQPSTATUS_CCQP_DONE,
0036 ICRDMA_CCQPSTATUS_CCQP_ERR,
0037 ICRDMA_CQPSQ_STAG_PDID,
0038 ICRDMA_CQPSQ_CQ_CEQID,
0039 ICRDMA_CQPSQ_CQ_CQID,
0040 ICRDMA_COMMIT_FPM_CQCNT,
0041 };
0042
0043 static u64 icrdma_shifts[IRDMA_MAX_SHIFTS] = {
0044 ICRDMA_CCQPSTATUS_CCQP_DONE_S,
0045 ICRDMA_CCQPSTATUS_CCQP_ERR_S,
0046 ICRDMA_CQPSQ_STAG_PDID_S,
0047 ICRDMA_CQPSQ_CQ_CEQID_S,
0048 ICRDMA_CQPSQ_CQ_CQID_S,
0049 ICRDMA_COMMIT_FPM_CQCNT_S,
0050 };
0051
0052
0053
0054
0055
0056
0057 static void icrdma_ena_irq(struct irdma_sc_dev *dev, u32 idx)
0058 {
0059 u32 val;
0060 u32 interval = 0;
0061
0062 if (dev->ceq_itr && dev->aeq->msix_idx != idx)
0063 interval = dev->ceq_itr >> 1;
0064 val = FIELD_PREP(IRDMA_GLINT_DYN_CTL_ITR_INDX, 0) |
0065 FIELD_PREP(IRDMA_GLINT_DYN_CTL_INTERVAL, interval) |
0066 FIELD_PREP(IRDMA_GLINT_DYN_CTL_INTENA, 1) |
0067 FIELD_PREP(IRDMA_GLINT_DYN_CTL_CLEARPBA, 1);
0068
0069 if (dev->hw_attrs.uk_attrs.hw_rev != IRDMA_GEN_1)
0070 writel(val, dev->hw_regs[IRDMA_GLINT_DYN_CTL] + idx);
0071 else
0072 writel(val, dev->hw_regs[IRDMA_GLINT_DYN_CTL] + (idx - 1));
0073 }
0074
0075
0076
0077
0078
0079
0080 static void icrdma_disable_irq(struct irdma_sc_dev *dev, u32 idx)
0081 {
0082 if (dev->hw_attrs.uk_attrs.hw_rev != IRDMA_GEN_1)
0083 writel(0, dev->hw_regs[IRDMA_GLINT_DYN_CTL] + idx);
0084 else
0085 writel(0, dev->hw_regs[IRDMA_GLINT_DYN_CTL] + (idx - 1));
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095 static void icrdma_cfg_ceq(struct irdma_sc_dev *dev, u32 ceq_id, u32 idx,
0096 bool enable)
0097 {
0098 u32 reg_val;
0099
0100 reg_val = FIELD_PREP(IRDMA_GLINT_CEQCTL_CAUSE_ENA, enable) |
0101 FIELD_PREP(IRDMA_GLINT_CEQCTL_MSIX_INDX, idx) |
0102 FIELD_PREP(IRDMA_GLINT_CEQCTL_ITR_INDX, 3);
0103
0104 writel(reg_val, dev->hw_regs[IRDMA_GLINT_CEQCTL] + ceq_id);
0105 }
0106
0107 static const struct irdma_irq_ops icrdma_irq_ops = {
0108 .irdma_cfg_aeq = irdma_cfg_aeq,
0109 .irdma_cfg_ceq = icrdma_cfg_ceq,
0110 .irdma_dis_irq = icrdma_disable_irq,
0111 .irdma_en_irq = icrdma_ena_irq,
0112 };
0113
0114 void icrdma_init_hw(struct irdma_sc_dev *dev)
0115 {
0116 int i;
0117 u8 __iomem *hw_addr;
0118
0119 for (i = 0; i < IRDMA_MAX_REGS; ++i) {
0120 hw_addr = dev->hw->hw_addr;
0121
0122 if (i == IRDMA_DB_ADDR_OFFSET)
0123 hw_addr = NULL;
0124
0125 dev->hw_regs[i] = (u32 __iomem *)(hw_addr + icrdma_regs[i]);
0126 }
0127 dev->hw_attrs.max_hw_vf_fpm_id = IRDMA_MAX_VF_FPM_ID;
0128 dev->hw_attrs.first_hw_vf_fpm_id = IRDMA_FIRST_VF_FPM_ID;
0129
0130 for (i = 0; i < IRDMA_MAX_SHIFTS; ++i)
0131 dev->hw_shifts[i] = icrdma_shifts[i];
0132
0133 for (i = 0; i < IRDMA_MAX_MASKS; ++i)
0134 dev->hw_masks[i] = icrdma_masks[i];
0135
0136 dev->wqe_alloc_db = dev->hw_regs[IRDMA_WQEALLOC];
0137 dev->cq_arm_db = dev->hw_regs[IRDMA_CQARM];
0138 dev->aeq_alloc_db = dev->hw_regs[IRDMA_AEQALLOC];
0139 dev->cqp_db = dev->hw_regs[IRDMA_CQPDB];
0140 dev->cq_ack_db = dev->hw_regs[IRDMA_CQACK];
0141 dev->irq_ops = &icrdma_irq_ops;
0142 dev->hw_attrs.page_size_cap = SZ_4K | SZ_2M | SZ_1G;
0143 dev->hw_attrs.max_hw_ird = ICRDMA_MAX_IRD_SIZE;
0144 dev->hw_attrs.max_hw_ord = ICRDMA_MAX_ORD_SIZE;
0145 dev->hw_attrs.max_stat_inst = ICRDMA_MAX_STATS_COUNT;
0146
0147 dev->hw_attrs.uk_attrs.max_hw_sq_chunk = IRDMA_MAX_QUANTA_PER_WR;
0148 dev->hw_attrs.uk_attrs.feature_flags |= IRDMA_FEATURE_RTS_AE |
0149 IRDMA_FEATURE_CQ_RESIZE;
0150 }