Add packet pacing support for PFs. ecore client can request for enabling packet pacing at init time, if requested then ecore is going to skip MCoS and SRIOV configurations.
Signed-off-by: Rasesh Mody <rasesh.m...@cavium.com> --- drivers/net/qede/base/ecore.h | 16 ++++++++++- drivers/net/qede/base/ecore_dev.c | 47 ++++++++++++++++++++++++++++----- drivers/net/qede/base/ecore_dev_api.h | 3 +++ drivers/net/qede/base/ecore_l2.c | 36 ++++++++++++++++++++++--- drivers/net/qede/qede_main.c | 1 + 5 files changed, 91 insertions(+), 12 deletions(-) diff --git a/drivers/net/qede/base/ecore.h b/drivers/net/qede/base/ecore.h index c8e6311..b6541dc 100644 --- a/drivers/net/qede/base/ecore.h +++ b/drivers/net/qede/base/ecore.h @@ -41,6 +41,9 @@ ((FW_MAJOR_VERSION << 24) | (FW_MINOR_VERSION << 16) | \ (FW_REVISION_VERSION << 8) | FW_ENGINEERING_VERSION) +#define IS_ECORE_PACING(p_hwfn) \ + (!!(p_hwfn->b_en_pacing)) + #define MAX_HWFNS_PER_DEVICE 2 #define NAME_SIZE 128 /* @DPDK */ #define ECORE_WFQ_UNIT 100 @@ -680,6 +683,13 @@ struct ecore_hwfn { /* Mechanism for recovering from doorbell drop */ struct ecore_db_recovery_info db_recovery_info; + /* Enable/disable pacing, if request to enable then + * IOV and mcos configuration will be skipped. + * this actually reflects the value requested in + * struct ecore_hw_prepare_params by ecore client. + */ + bool b_en_pacing; + /* @DPDK */ struct ecore_ptt *p_arfs_ptt; }; @@ -932,12 +942,16 @@ void ecore_set_fw_mac_addr(__le16 *fw_msb, __le16 *fw_mid, __le16 *fw_lsb, #define PQ_FLAGS_ACK (1 << 4) #define PQ_FLAGS_OFLD (1 << 5) #define PQ_FLAGS_VFS (1 << 6) +#define PQ_FLAGS_LLT (1 << 7) /* physical queue index for cm context intialization */ u16 ecore_get_cm_pq_idx(struct ecore_hwfn *p_hwfn, u32 pq_flags); u16 ecore_get_cm_pq_idx_mcos(struct ecore_hwfn *p_hwfn, u8 tc); u16 ecore_get_cm_pq_idx_vf(struct ecore_hwfn *p_hwfn, u16 vf); -u16 ecore_get_cm_pq_idx_rl(struct ecore_hwfn *p_hwfn, u8 qpid); +u16 ecore_get_cm_pq_idx_rl(struct ecore_hwfn *p_hwfn, u16 rl); + +/* qm vport for rate limit configuration */ +u16 ecore_get_qm_vport_idx_rl(struct ecore_hwfn *p_hwfn, u16 rl); const char *ecore_hw_get_resc_name(enum ecore_resources res_id); diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c index 112f854..b1e67e2 100644 --- a/drivers/net/qede/base/ecore_dev.c +++ b/drivers/net/qede/base/ecore_dev.c @@ -513,11 +513,14 @@ static u32 ecore_get_pq_flags(struct ecore_hwfn *p_hwfn) /* feature flags */ if (IS_ECORE_SRIOV(p_hwfn->p_dev)) flags |= PQ_FLAGS_VFS; + if (IS_ECORE_PACING(p_hwfn)) + flags |= PQ_FLAGS_RLS; /* protocol flags */ switch (p_hwfn->hw_info.personality) { case ECORE_PCI_ETH: - flags |= PQ_FLAGS_MCOS; + if (!IS_ECORE_PACING(p_hwfn)) + flags |= PQ_FLAGS_MCOS; break; case ECORE_PCI_FCOE: flags |= PQ_FLAGS_OFLD; @@ -526,11 +529,14 @@ static u32 ecore_get_pq_flags(struct ecore_hwfn *p_hwfn) flags |= PQ_FLAGS_ACK | PQ_FLAGS_OOO | PQ_FLAGS_OFLD; break; case ECORE_PCI_ETH_ROCE: - flags |= PQ_FLAGS_MCOS | PQ_FLAGS_OFLD; + flags |= PQ_FLAGS_OFLD | PQ_FLAGS_LLT; + if (!IS_ECORE_PACING(p_hwfn)) + flags |= PQ_FLAGS_MCOS; break; case ECORE_PCI_ETH_IWARP: - flags |= PQ_FLAGS_MCOS | PQ_FLAGS_ACK | PQ_FLAGS_OOO | - PQ_FLAGS_OFLD; + flags |= PQ_FLAGS_ACK | PQ_FLAGS_OOO | PQ_FLAGS_OFLD; + if (!IS_ECORE_PACING(p_hwfn)) + flags |= PQ_FLAGS_MCOS; break; default: DP_ERR(p_hwfn, "unknown personality %d\n", @@ -837,7 +843,7 @@ u16 ecore_get_cm_pq_idx_vf(struct ecore_hwfn *p_hwfn, u16 vf) return ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + vf; } -u16 ecore_get_cm_pq_idx_rl(struct ecore_hwfn *p_hwfn, u8 rl) +u16 ecore_get_cm_pq_idx_rl(struct ecore_hwfn *p_hwfn, u16 rl) { u16 max_rl = ecore_init_qm_get_num_pf_rls(p_hwfn); @@ -847,6 +853,23 @@ u16 ecore_get_cm_pq_idx_rl(struct ecore_hwfn *p_hwfn, u8 rl) return ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_RLS) + rl; } +u16 ecore_get_qm_vport_idx_rl(struct ecore_hwfn *p_hwfn, u16 rl) +{ + u16 start_pq, pq, qm_pq_idx; + + pq = ecore_get_cm_pq_idx_rl(p_hwfn, rl); + start_pq = p_hwfn->qm_info.start_pq; + qm_pq_idx = pq - start_pq - CM_TX_PQ_BASE; + + if (qm_pq_idx > p_hwfn->qm_info.num_pqs) { + DP_ERR(p_hwfn, + "qm_pq_idx %d must be smaller than %d\n", + qm_pq_idx, p_hwfn->qm_info.num_pqs); + } + + return p_hwfn->qm_info.qm_pq_params[qm_pq_idx].vport_id; +} + /* Functions for creating specific types of pqs */ static void ecore_init_qm_lb_pq(struct ecore_hwfn *p_hwfn) { @@ -3878,8 +3901,13 @@ static void ecore_mcp_get_eee_caps(struct ecore_hwfn *p_hwfn, bool drv_resc_alloc = p_params->drv_resc_alloc; enum _ecore_status_t rc; + if (IS_ECORE_PACING(p_hwfn)) { + DP_VERBOSE(p_hwfn->p_dev, ECORE_MSG_IOV, + "Skipping IOV as packet pacing is requested\n"); + } + /* Since all information is common, only first hwfns should do this */ - if (IS_LEAD_HWFN(p_hwfn)) { + if (IS_LEAD_HWFN(p_hwfn) && !IS_ECORE_PACING(p_hwfn)) { rc = ecore_iov_hw_info(p_hwfn); if (rc != ECORE_SUCCESS) { if (p_params->b_relaxed_probe) @@ -3964,7 +3992,10 @@ static void ecore_mcp_get_eee_caps(struct ecore_hwfn *p_hwfn, * that can result in performance penalty in some cases. 4 * represents a good tradeoff between performance and flexibility. */ - p_hwfn->hw_info.num_hw_tc = NUM_PHYS_TCS_4PORT_K2; + if (IS_ECORE_PACING(p_hwfn)) + p_hwfn->hw_info.num_hw_tc = 1; + else + p_hwfn->hw_info.num_hw_tc = NUM_PHYS_TCS_4PORT_K2; /* start out with a single active tc. This can be increased either * by dcbx negotiation or by upper layer driver @@ -4251,6 +4282,7 @@ enum _ecore_status_t ecore_hw_prepare(struct ecore_dev *p_dev, p_dev->chk_reg_fifo = p_params->chk_reg_fifo; p_dev->allow_mdump = p_params->allow_mdump; + p_hwfn->b_en_pacing = p_params->b_en_pacing; if (p_params->b_relaxed_probe) p_params->p_relaxed_res = ECORE_HW_PREPARE_SUCCESS; @@ -4286,6 +4318,7 @@ enum _ecore_status_t ecore_hw_prepare(struct ecore_dev *p_dev, BAR_ID_1) / 2; p_doorbell = (void OSAL_IOMEM *)addr; + p_dev->hwfns[1].b_en_pacing = p_params->b_en_pacing; /* prepare second hw function */ rc = ecore_hw_prepare_single(&p_dev->hwfns[1], p_regview, p_doorbell, p_params); diff --git a/drivers/net/qede/base/ecore_dev_api.h b/drivers/net/qede/base/ecore_dev_api.h index f619683..29fb74b 100644 --- a/drivers/net/qede/base/ecore_dev_api.h +++ b/drivers/net/qede/base/ecore_dev_api.h @@ -270,6 +270,9 @@ struct ecore_hw_prepare_params { */ bool b_relaxed_probe; enum ecore_hw_prepare_result p_relaxed_res; + + /* Enable/disable request by ecore client for pacing */ + bool b_en_pacing; }; /** diff --git a/drivers/net/qede/base/ecore_l2.c b/drivers/net/qede/base/ecore_l2.c index 0883fd3..c897fa5 100644 --- a/drivers/net/qede/base/ecore_l2.c +++ b/drivers/net/qede/base/ecore_l2.c @@ -1188,11 +1188,20 @@ enum _ecore_status_t void OSAL_IOMEM * *pp_doorbell) { enum _ecore_status_t rc; + u16 pq_id; - /* TODO - set tc in the pq_params for multi-cos */ - rc = ecore_eth_txq_start_ramrod(p_hwfn, p_cid, - pbl_addr, pbl_size, - ecore_get_cm_pq_idx_mcos(p_hwfn, tc)); + /* TODO - set tc in the pq_params for multi-cos. + * If pacing is enabled then select queue according to + * rate limiter availability otherwise select queue based + * on multi cos. + */ + if (IS_ECORE_PACING(p_hwfn)) + pq_id = ecore_get_cm_pq_idx_rl(p_hwfn, p_cid->rel.queue_id); + else + pq_id = ecore_get_cm_pq_idx_mcos(p_hwfn, tc); + + rc = ecore_eth_txq_start_ramrod(p_hwfn, p_cid, pbl_addr, + pbl_size, pq_id); if (rc != ECORE_SUCCESS) return rc; @@ -2278,3 +2287,22 @@ enum _ecore_status_t return rc; } + +enum _ecore_status_t +ecore_eth_tx_queue_maxrate(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt, + struct ecore_queue_cid *p_cid, u32 rate) +{ + struct ecore_mcp_link_state *p_link; + u8 vport; + + vport = (u8)ecore_get_qm_vport_idx_rl(p_hwfn, p_cid->rel.queue_id); + p_link = &ECORE_LEADING_HWFN(p_hwfn->p_dev)->mcp_info->link_output; + + DP_VERBOSE(p_hwfn, ECORE_MSG_LINK, + "About to rate limit qm vport %d for queue %d with rate %d\n", + vport, p_cid->rel.queue_id, rate); + + return ecore_init_vport_rl(p_hwfn, p_ptt, vport, rate, + p_link->speed); +} diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c index 650f2cf..2333ca0 100644 --- a/drivers/net/qede/qede_main.c +++ b/drivers/net/qede/qede_main.c @@ -62,6 +62,7 @@ static void qed_init_pci(struct ecore_dev *edev, struct rte_pci_device *pci_dev) hw_prepare_params.chk_reg_fifo = false; hw_prepare_params.initiate_pf_flr = true; hw_prepare_params.allow_mdump = false; + hw_prepare_params.b_en_pacing = false; hw_prepare_params.epoch = (u32)time(NULL); rc = ecore_hw_prepare(edev, &hw_prepare_params); if (rc) { -- 1.7.10.3