[dpdk-dev] [PATCH 01/17] net/qede/base: fix to handle stag update event
This fix adds a ecore_mcp_update_stag() handler to handle the STAG update events from management FW and program the STAG value. It also clears the stag config on PF, when management FW invalidates the stag value. Fixes: ec94dbc57362 ("qede: add base driver") Cc: sta...@dpdk.org Signed-off-by: Rasesh Mody --- drivers/net/qede/base/bcm_osal.h |1 + drivers/net/qede/base/ecore_mcp.c | 46 + drivers/net/qede/base/ecore_mcp_api.h |4 +++ drivers/net/qede/base/mcp_public.h|1 + drivers/net/qede/base/reg_addr.h |5 5 files changed, 57 insertions(+) diff --git a/drivers/net/qede/base/bcm_osal.h b/drivers/net/qede/base/bcm_osal.h index 630867f..b43e0b3 100644 --- a/drivers/net/qede/base/bcm_osal.h +++ b/drivers/net/qede/base/bcm_osal.h @@ -447,6 +447,7 @@ void qede_get_mcp_proto_stats(struct ecore_dev *, enum ecore_mcp_protocol_type, #define OSAL_CRC8(table, pdata, nbytes, crc) 0 #define OSAL_MFW_TLV_REQ(p_hwfn) nothing #define OSAL_MFW_FILL_TLV_DATA(type, buf, data) (0) +#define OSAL_HW_INFO_CHANGE(p_hwfn, change) nothing #define OSAL_MFW_CMD_PREEMPT(p_hwfn) nothing #define OSAL_PF_VALIDATE_MODIFY_TUNN_CONFIG(p_hwfn, mask, b_update, tunn) 0 diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c index ea14c17..49963c6 100644 --- a/drivers/net/qede/base/ecore_mcp.c +++ b/drivers/net/qede/base/ecore_mcp.c @@ -1656,6 +1656,49 @@ static void ecore_read_pf_bandwidth(struct ecore_hwfn *p_hwfn, ¶m); } +static void ecore_mcp_update_stag(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt) +{ + struct public_func shmem_info; + u32 resp = 0, param = 0; + + ecore_mcp_get_shmem_func(p_hwfn, p_ptt, &shmem_info, +MCP_PF_ID(p_hwfn)); + + p_hwfn->mcp_info->func_info.ovlan = (u16)shmem_info.ovlan_stag & +FUNC_MF_CFG_OV_STAG_MASK; + p_hwfn->hw_info.ovlan = p_hwfn->mcp_info->func_info.ovlan; + if (OSAL_TEST_BIT(ECORE_MF_OVLAN_CLSS, &p_hwfn->p_dev->mf_bits)) { + if (p_hwfn->hw_info.ovlan != ECORE_MCP_VLAN_UNSET) { + ecore_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_VALUE, +p_hwfn->hw_info.ovlan); + ecore_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_EN, 1); + + /* Configure DB to add external vlan to EDPM packets */ + ecore_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 1); + ecore_wr(p_hwfn, p_ptt, DORQ_REG_PF_EXT_VID_BB_K2, +p_hwfn->hw_info.ovlan); + } else { + ecore_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_EN, 0); + ecore_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_VALUE, 0); + + /* Configure DB to add external vlan to EDPM packets */ + ecore_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 0); + ecore_wr(p_hwfn, p_ptt, DORQ_REG_PF_EXT_VID_BB_K2, 0); + } + + ecore_sp_pf_update_stag(p_hwfn); + } + + DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "ovlan = %d hw_mode = 0x%x\n", + p_hwfn->mcp_info->func_info.ovlan, p_hwfn->hw_info.hw_mode); + OSAL_HW_INFO_CHANGE(p_hwfn, ECORE_HW_INFO_CHANGE_OVLAN); + + /* Acknowledge the MFW */ + ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_S_TAG_UPDATE_ACK, 0, + &resp, ¶m); +} + static void ecore_mcp_handle_fan_failure(struct ecore_hwfn *p_hwfn) { /* A single notification should be sent to upper driver in CMT mode */ @@ -2041,6 +2084,9 @@ enum _ecore_status_t ecore_mcp_handle_events(struct ecore_hwfn *p_hwfn, case MFW_DRV_MSG_BW_UPDATE: ecore_mcp_update_bw(p_hwfn, p_ptt); break; + case MFW_DRV_MSG_S_TAG_UPDATE: + ecore_mcp_update_stag(p_hwfn, p_ptt); + break; case MFW_DRV_MSG_FAILURE_DETECTED: ecore_mcp_handle_fan_failure(p_hwfn); break; diff --git a/drivers/net/qede/base/ecore_mcp_api.h b/drivers/net/qede/base/ecore_mcp_api.h index cfb9f99..8f4efd1 100644 --- a/drivers/net/qede/base/ecore_mcp_api.h +++ b/drivers/net/qede/base/ecore_mcp_api.h @@ -521,6 +521,10 @@ struct ecore_mfw_tlv_iscsi { struct ecore_mfw_tlv_iscsi iscsi; }; +enum ecore_hw_info_change { + ECORE_HW_INFO_CHANGE_OVLAN, +}; + /** * @brief - returns the link params of the hw function * diff --git a/drivers/net/qede/base/mcp_public.h b/drivers/net/qede/base/mcp_public.h index 81aa88e..79d9aae 100644 --- a/drivers/net/qede/base/mcp_public.h +++ b/drivers/net/qede/base/mcp_public.h @@ -1258,6 +1258,7 @@ struct public_drv_mb { */ #define DRV_MSG_GET_RESOURCE_ALLOC_MSG 0x340
[dpdk-dev] [PATCH 00/17] net/qede: add enhancements and fixes
This patchset adds enhancements and fixes for QEDE PMD. Rasesh Mody (8): net/qede/base: fix to handle stag update event net/qede/base: add support for OneView APIs net/qede/base: get pre-negotiated values for stag and bw net/qede: fix to program HW regs with ether type net/qede/base: limit number of non ethernet queues to 64 net/qede/base: correct MCP error handler's log verbosity net/qede/base: fix logic for sfp get/set net/qede/base: use pointer for bytes len read Shahed Shaikh (9): net/qede/base: use trust mode for forced MAC limitations net/qede: reorganize filter code net/qede: fix flow director bug for IPv6 filter net/qede: refactor fdir code into generic aRFS net/qede: add support for generic flow API net/qede: fix Rx buffer size calculation net/qede: add support for Rx descriptor status net/qede/base: fix MFW FLR flow bug net/qede: add support for dev reset drivers/net/qede/Makefile |2 +- drivers/net/qede/base/bcm_osal.h |1 + drivers/net/qede/base/ecore.h |3 + drivers/net/qede/base/ecore_dev.c | 85 +- drivers/net/qede/base/ecore_dev_api.h |3 + drivers/net/qede/base/ecore_int.c | 32 + drivers/net/qede/base/ecore_int.h |1 + drivers/net/qede/base/ecore_iov_api.h |7 + drivers/net/qede/base/ecore_l2.c | 26 +- drivers/net/qede/base/ecore_l2_api.h | 11 +- drivers/net/qede/base/ecore_mcp.c | 157 +++- drivers/net/qede/base/ecore_mcp_api.h | 40 +- drivers/net/qede/base/ecore_sriov.c | 36 +- drivers/net/qede/base/mcp_public.h| 21 + drivers/net/qede/base/reg_addr.h | 20 + drivers/net/qede/qede_ethdev.c| 724 +-- drivers/net/qede/qede_ethdev.h| 65 +- drivers/net/qede/qede_fdir.c | 470 -- drivers/net/qede/qede_filter.c| 1546 + drivers/net/qede/qede_rxtx.c | 140 ++- drivers/net/qede/qede_rxtx.h | 17 +- 21 files changed, 2177 insertions(+), 1230 deletions(-) delete mode 100644 drivers/net/qede/qede_fdir.c create mode 100644 drivers/net/qede/qede_filter.c -- 1.7.10.3
[dpdk-dev] [PATCH 02/17] net/qede/base: add support for OneView APIs
Add support for the following OneView APIs: - ecore_mcp_ov_update_mtu() - Send MTU value to the management FW. - ecore_mcp_ov_update_mac() - Send MAC address to the management FW. - ecore_mcp_ov_update_eswitch() - Send eswitch_mode to management FW after the firmware load. Signed-off-by: Rasesh Mody --- drivers/net/qede/base/ecore_dev.c | 12 -- drivers/net/qede/base/ecore_mcp.c | 68 +++-- drivers/net/qede/base/ecore_mcp_api.h | 32 drivers/net/qede/base/mcp_public.h| 15 4 files changed, 121 insertions(+), 6 deletions(-) diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c index 31f1f3e..be68a12 100644 --- a/drivers/net/qede/base/ecore_dev.c +++ b/drivers/net/qede/base/ecore_dev.c @@ -2599,17 +2599,23 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev, if (rc != ECORE_SUCCESS) DP_INFO(p_hwfn, "Failed to update firmware version\n"); - if (!b_default_mtu) + if (!b_default_mtu) { rc = ecore_mcp_ov_update_mtu(p_hwfn, p_hwfn->p_main_ptt, p_hwfn->hw_info.mtu); - if (rc != ECORE_SUCCESS) - DP_INFO(p_hwfn, "Failed to update default mtu\n"); + if (rc != ECORE_SUCCESS) + DP_INFO(p_hwfn, "Failed to update default mtu\n"); + } rc = ecore_mcp_ov_update_driver_state(p_hwfn, p_hwfn->p_main_ptt, ECORE_OV_DRIVER_STATE_DISABLED); if (rc != ECORE_SUCCESS) DP_INFO(p_hwfn, "Failed to update driver state\n"); + + rc = ecore_mcp_ov_update_eswitch(p_hwfn, p_hwfn->p_main_ptt, +ECORE_OV_ESWITCH_NONE); + if (rc != ECORE_SUCCESS) + DP_INFO(p_hwfn, "Failed to update eswitch mode\n"); } return rc; diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c index 49963c6..1b6fc0a 100644 --- a/drivers/net/qede/base/ecore_mcp.c +++ b/drivers/net/qede/base/ecore_mcp.c @@ -2869,10 +2869,72 @@ enum _ecore_status_t } enum _ecore_status_t -ecore_mcp_ov_update_mtu(struct ecore_hwfn *p_hwfn, - struct ecore_ptt *p_ptt, u16 mtu) +ecore_mcp_ov_update_mtu(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, + u16 mtu) { - return 0; + u32 resp = 0, param = 0, drv_mb_param = 0; + enum _ecore_status_t rc; + + SET_MFW_FIELD(drv_mb_param, DRV_MB_PARAM_OV_MTU_SIZE, (u32)mtu); + rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_OV_UPDATE_MTU, + drv_mb_param, &resp, ¶m); + if (rc != ECORE_SUCCESS) + DP_ERR(p_hwfn, "Failed to send mtu value, rc = %d\n", rc); + + return rc; +} + +enum _ecore_status_t +ecore_mcp_ov_update_mac(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, + u8 *mac) +{ + struct ecore_mcp_mb_params mb_params; + union drv_union_data union_data; + enum _ecore_status_t rc; + + OSAL_MEM_ZERO(&mb_params, sizeof(mb_params)); + mb_params.cmd = DRV_MSG_CODE_SET_VMAC; + SET_MFW_FIELD(mb_params.param, DRV_MSG_CODE_VMAC_TYPE, + DRV_MSG_CODE_VMAC_TYPE_MAC); + mb_params.param |= MCP_PF_ID(p_hwfn); + OSAL_MEMCPY(&union_data.raw_data, mac, ETH_ALEN); + mb_params.p_data_src = &union_data; + rc = ecore_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params); + if (rc != ECORE_SUCCESS) + DP_ERR(p_hwfn, "Failed to send mac address, rc = %d\n", rc); + + return rc; +} + +enum _ecore_status_t +ecore_mcp_ov_update_eswitch(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, + enum ecore_ov_eswitch eswitch) +{ + enum _ecore_status_t rc; + u32 resp = 0, param = 0; + u32 drv_mb_param; + + switch (eswitch) { + case ECORE_OV_ESWITCH_NONE: + drv_mb_param = DRV_MB_PARAM_ESWITCH_MODE_NONE; + break; + case ECORE_OV_ESWITCH_VEB: + drv_mb_param = DRV_MB_PARAM_ESWITCH_MODE_VEB; + break; + case ECORE_OV_ESWITCH_VEPA: + drv_mb_param = DRV_MB_PARAM_ESWITCH_MODE_VEPA; + break; + default: + DP_ERR(p_hwfn, "Invalid eswitch mode %d\n", eswitch); + return ECORE_INVAL; + } + + rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_OV_UPDATE_ESWITCH_MODE, + drv_mb_param, &resp, ¶m); + if (rc != ECORE_SUCCESS) + DP_ERR(p_hwfn, "Failed to send eswitch mode, rc = %d\n", rc); + + return rc; } enum _ecore_status_t ecore_mcp_set_led(struct e
[dpdk-dev] [PATCH 03/17] net/qede/base: get pre-negotiated values for stag and bw
Request management FW for STAG and bandwidth values negotiated prior to the driver load. Signed-off-by: Rasesh Mody --- drivers/net/qede/base/ecore_dev.c | 14 ++ drivers/net/qede/base/mcp_public.h |3 +++ 2 files changed, 17 insertions(+) diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c index be68a12..958d7a0 100644 --- a/drivers/net/qede/base/ecore_dev.c +++ b/drivers/net/qede/base/ecore_dev.c @@ -2591,6 +2591,20 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev, } if (IS_PF(p_dev)) { + /* Get pre-negotiated values for stag, bandwidth etc. */ + p_hwfn = ECORE_LEADING_HWFN(p_dev); + DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, + "Sending GET_OEM_UPDATES command to trigger stag/bandwidth attention handling\n"); + rc = ecore_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt, + DRV_MSG_CODE_GET_OEM_UPDATES, + 1 << DRV_MB_PARAM_DUMMY_OEM_UPDATES_OFFSET, + &resp, ¶m); + if (rc != ECORE_SUCCESS) + DP_NOTICE(p_hwfn, false, + "Failed to send GET_OEM_UPDATES attention request\n"); + } + + if (IS_PF(p_dev)) { p_hwfn = ECORE_LEADING_HWFN(p_dev); drv_mb_param = STORM_FW_VERSION; rc = ecore_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt, diff --git a/drivers/net/qede/base/mcp_public.h b/drivers/net/qede/base/mcp_public.h index 5575d9d..e9f3350 100644 --- a/drivers/net/qede/base/mcp_public.h +++ b/drivers/net/qede/base/mcp_public.h @@ -1598,6 +1598,9 @@ struct public_drv_mb { #define DRV_MB_PARAM_ESWITCH_MODE_VEB 0x1 #define DRV_MB_PARAM_ESWITCH_MODE_VEPA 0x2 +#define DRV_MB_PARAM_DUMMY_OEM_UPDATES_MASK 0x1 +#define DRV_MB_PARAM_DUMMY_OEM_UPDATES_OFFSET 0 + #define DRV_MB_PARAM_SET_LED_MODE_OPER 0x0 #define DRV_MB_PARAM_SET_LED_MODE_ON 0x1 #define DRV_MB_PARAM_SET_LED_MODE_OFF 0x2 -- 1.7.10.3
[dpdk-dev] [PATCH 06/17] net/qede/base: correct MCP error handler's log verbosity
Correct the verbosity for slowpath message from DCB to SP. Signed-off-by: Rasesh Mody --- drivers/net/qede/base/ecore_mcp.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c index 1b6fc0a..1b6eb94 100644 --- a/drivers/net/qede/base/ecore_mcp.c +++ b/drivers/net/qede/base/ecore_mcp.c @@ -1989,7 +1989,7 @@ static void ecore_mcp_handle_critical_error(struct ecore_hwfn *p_hwfn, DP_NOTICE(p_hwfn, false, "Unknown Host priority control %d\n", val); - DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, + DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "UFP shmem config: mode = %d tc = %d pri_type = %d\n", p_hwfn->ufp_info.mode, p_hwfn->ufp_info.tc, p_hwfn->ufp_info.pri_type); -- 1.7.10.3
[dpdk-dev] [PATCH 07/17] net/qede/base: fix logic for sfp get/set
Fix logic for sfp get rx_los, tx_fault, tx_disable, and sfp set tx_disable. Fixes: bdc40630a8eb ("net/qede/base: add APIs for xcvr") Cc: sta...@dpdk.org Signed-off-by: Rasesh Mody --- drivers/net/qede/base/ecore_mcp.c | 37 - drivers/net/qede/base/ecore_mcp_api.h |2 ++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c index 1b6eb94..ea71d07 100644 --- a/drivers/net/qede/base/ecore_mcp.c +++ b/drivers/net/qede/base/ecore_mcp.c @@ -2201,8 +2201,10 @@ enum _ecore_status_t ecore_mcp_get_media_type(struct ecore_hwfn *p_hwfn, enum _ecore_status_t ecore_mcp_get_transceiver_data(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, - u32 *p_tranceiver_type) + u32 *p_transceiver_state, + u32 *p_transceiver_type) { + u32 transceiver_info; enum _ecore_status_t rc = ECORE_SUCCESS; /* TODO - Add support for VFs */ @@ -2213,14 +2215,23 @@ enum _ecore_status_t ecore_mcp_get_transceiver_data(struct ecore_hwfn *p_hwfn, DP_NOTICE(p_hwfn, false, "MFW is not initialized!\n"); return ECORE_BUSY; } - if (!p_ptt) { - *p_tranceiver_type = ETH_TRANSCEIVER_TYPE_NONE; - rc = ECORE_INVAL; + + *p_transceiver_type = ETH_TRANSCEIVER_TYPE_NONE; + *p_transceiver_state = ETH_TRANSCEIVER_STATE_UPDATING; + + transceiver_info = ecore_rd(p_hwfn, p_ptt, + p_hwfn->mcp_info->port_addr + + offsetof(struct public_port, + transceiver_data)); + + *p_transceiver_state = GET_MFW_FIELD(transceiver_info, +ETH_TRANSCEIVER_STATE); + + if (*p_transceiver_state == ETH_TRANSCEIVER_STATE_PRESENT) { + *p_transceiver_type = GET_MFW_FIELD(transceiver_info, + ETH_TRANSCEIVER_TYPE); } else { - *p_tranceiver_type = ecore_rd(p_hwfn, p_ptt, - p_hwfn->mcp_info->port_addr + - offsetof(struct public_port, - transceiver_data)); + *p_transceiver_type = ETH_TRANSCEIVER_TYPE_UNKNOWN; } return rc; @@ -2240,15 +2251,11 @@ enum _ecore_status_t ecore_mcp_trans_speed_mask(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, u32 *p_speed_mask) { - u32 transceiver_data, transceiver_type, transceiver_state; - - ecore_mcp_get_transceiver_data(p_hwfn, p_ptt, &transceiver_data); + u32 transceiver_type, transceiver_state; - transceiver_state = GET_MFW_FIELD(transceiver_data, - ETH_TRANSCEIVER_STATE); + ecore_mcp_get_transceiver_data(p_hwfn, p_ptt, &transceiver_state, + &transceiver_type); - transceiver_type = GET_MFW_FIELD(transceiver_data, - ETH_TRANSCEIVER_TYPE); if (is_transceiver_ready(transceiver_state, transceiver_type) == 0) return ECORE_INVAL; diff --git a/drivers/net/qede/base/ecore_mcp_api.h b/drivers/net/qede/base/ecore_mcp_api.h index 0103293..4098bae 100644 --- a/drivers/net/qede/base/ecore_mcp_api.h +++ b/drivers/net/qede/base/ecore_mcp_api.h @@ -607,6 +607,7 @@ enum _ecore_status_t ecore_mcp_get_media_type(struct ecore_hwfn *p_hwfn, * * @param p_dev - ecore dev pointer * @param p_ptt + * @param p_transceiver_state - transceiver state. * @param p_transceiver_type - media type value * * @return enum _ecore_status_t - @@ -615,6 +616,7 @@ enum _ecore_status_t ecore_mcp_get_media_type(struct ecore_hwfn *p_hwfn, */ enum _ecore_status_t ecore_mcp_get_transceiver_data(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, + u32 *p_transceiver_state, u32 *p_tranceiver_type); /** -- 1.7.10.3
[dpdk-dev] [PATCH 08/17] net/qede/base: use trust mode for forced MAC limitations
From: Shahed Shaikh When trust mode is set to ON, VF can change it's MAC address inspite PF has set a forced MAC for that VF from HV. Earlier similar functionality is provided by module parameter "allow_vf_mac_change_mode" of qed. This change makes few changes in behavior of VF shadow config - - Let driver track the VF mac in shadow config as long as trust mode is OFF. - Once trust mode is ON, we should not care about MACs in shadow config (because we never intend to fall back because of lack of restore implementation). - Delete existing shadow MAC (this helps when trust mode is turned OFF, and VF tries to add new MAC – it won’t fail that time since we have a clean slate). - Skip addition and deletion of MACs in shadow configs. Signed-off-by: Shahed Shaikh --- drivers/net/qede/base/ecore_iov_api.h |7 +++ drivers/net/qede/base/ecore_sriov.c | 36 - 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/drivers/net/qede/base/ecore_iov_api.h b/drivers/net/qede/base/ecore_iov_api.h index 29001d7..d398478 100644 --- a/drivers/net/qede/base/ecore_iov_api.h +++ b/drivers/net/qede/base/ecore_iov_api.h @@ -84,6 +84,13 @@ struct ecore_public_vf_info { */ u8 forced_mac[ETH_ALEN]; u16 forced_vlan; + + /* Trusted VFs can configure promiscuous mode and +* set MAC address inspite PF has set forced MAC. +* Also store shadow promisc configuration if needed. +*/ + bool is_trusted_configured; + bool is_trusted_request; }; struct ecore_iov_vf_init_params { diff --git a/drivers/net/qede/base/ecore_sriov.c b/drivers/net/qede/base/ecore_sriov.c index f7ebf7a..9e4a57b 100644 --- a/drivers/net/qede/base/ecore_sriov.c +++ b/drivers/net/qede/base/ecore_sriov.c @@ -1968,7 +1968,8 @@ static void ecore_iov_vf_mbx_acquire(struct ecore_hwfn *p_hwfn, return ECORE_INVAL; if ((events & (1 << MAC_ADDR_FORCED)) || - p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change) { + p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change || + p_vf->p_vf_info.is_trusted_configured) { /* Since there's no way [currently] of removing the MAC, * we can always assume this means we need to force it. */ @@ -1989,7 +1990,8 @@ static void ecore_iov_vf_mbx_acquire(struct ecore_hwfn *p_hwfn, return rc; } - if (p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change) + if (p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change || + p_vf->p_vf_info.is_trusted_configured) p_vf->configured_features |= 1 << VFPF_BULLETIN_MAC_ADDR; else @@ -3351,6 +3353,15 @@ static void ecore_iov_vf_mbx_vport_update(struct ecore_hwfn *p_hwfn, if (p_vf->bulletin.p_virt->valid_bitmap & (1 << MAC_ADDR_FORCED)) return ECORE_SUCCESS; + /* Since we don't have the implementation of the logic for removing +* a forced MAC and restoring shadow MAC, let's not worry about +* processing shadow copies of MAC as long as VF trust mode is ON, +* to keep things simple. +*/ + if (p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change || + p_vf->p_vf_info.is_trusted_configured) + return ECORE_SUCCESS; + /* First remove entries and then add new ones */ if (p_params->opcode == ECORE_FILTER_REMOVE) { for (i = 0; i < ECORE_ETH_VF_NUM_MAC_FILTERS; i++) { @@ -4415,17 +4426,23 @@ void ecore_iov_bulletin_set_forced_mac(struct ecore_hwfn *p_hwfn, return; } - if (p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change) + if (p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change || + vf_info->p_vf_info.is_trusted_configured) { feature = 1 << VFPF_BULLETIN_MAC_ADDR; - else + /* Trust mode will disable Forced MAC */ + vf_info->bulletin.p_virt->valid_bitmap &= + ~(1 << MAC_ADDR_FORCED); + } else { feature = 1 << MAC_ADDR_FORCED; + /* Forced MAC will disable MAC_ADDR */ + vf_info->bulletin.p_virt->valid_bitmap &= + ~(1 << VFPF_BULLETIN_MAC_ADDR); + } - OSAL_MEMCPY(vf_info->bulletin.p_virt->mac, mac, ETH_ALEN); + OSAL_MEMCPY(vf_info->bulletin.p_virt->mac, + mac, ETH_ALEN); vf_info->bulletin.p_virt->valid_bitmap |= feature; - /* Forced MAC will disable MAC_ADDR */ - vf_info->bulletin.p_virt->valid_bitmap &= - ~(1 << VFPF_BULLETIN_MAC_ADDR); ecore_iov_configure_vport_forced(p_hwfn, vf_info, feature); } @@ -4460,7 +4477,8 @@ enum _ecore_status_t ecore_iov_bulletin_set_mac(struct ecore_hwfn *p_hwfn, vf_info->bulletin.p_vi
[dpdk-dev] [PATCH 04/17] net/qede: fix to program HW regs with ether type
Fix to program the HW registers with proper ether type. Fixes: 36f45bce2537 ("net/qede/base: fix to support OVLAN mode") Cc: sta...@dpdk.org Signed-off-by: Rasesh Mody --- drivers/net/qede/base/ecore_dev.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c index 958d7a0..6302abc 100644 --- a/drivers/net/qede/base/ecore_dev.c +++ b/drivers/net/qede/base/ecore_dev.c @@ -2410,6 +2410,7 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev, bool b_default_mtu = true; struct ecore_hwfn *p_hwfn; enum _ecore_status_t rc = ECORE_SUCCESS; + u16 ether_type; int i; if ((p_params->int_mode == ECORE_INT_MODE_MSI) && ECORE_IS_CMT(p_dev)) { @@ -2442,6 +2443,25 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev, if (rc != ECORE_SUCCESS) return rc; + if (IS_PF(p_dev) && (OSAL_TEST_BIT(ECORE_MF_8021Q_TAGGING, + &p_dev->mf_bits) || +OSAL_TEST_BIT(ECORE_MF_8021AD_TAGGING, + &p_dev->mf_bits))) { + if (OSAL_TEST_BIT(ECORE_MF_8021Q_TAGGING, + &p_dev->mf_bits)) + ether_type = ETHER_TYPE_VLAN; + else + ether_type = ETHER_TYPE_QINQ; + STORE_RT_REG(p_hwfn, PRS_REG_TAG_ETHERTYPE_0_RT_OFFSET, +ether_type); + STORE_RT_REG(p_hwfn, NIG_REG_TAG_ETHERTYPE_0_RT_OFFSET, +ether_type); + STORE_RT_REG(p_hwfn, PBF_REG_TAG_ETHERTYPE_0_RT_OFFSET, +ether_type); + STORE_RT_REG(p_hwfn, DORQ_REG_TAG1_ETHERTYPE_RT_OFFSET, +ether_type); + } + ecore_set_spq_block_timeout(p_hwfn, p_params->spq_timeout_ms); rc = ecore_fill_load_req_params(p_hwfn, &load_req_params, -- 1.7.10.3
[dpdk-dev] [PATCH 05/17] net/qede/base: limit number of non ethernet queues to 64
Limit the number of non ethernet queues to 64, allowing a max queues to status block ratio of 2:1 in case of storage target. Theoretically a non-target storage PF can have 128 queues and SBs. This change is to support 64 entries for a target iSCSI/FCoE PF and 128 for a non-target. Signed-off-by: Rasesh Mody --- drivers/net/qede/base/ecore.h |3 +++ drivers/net/qede/base/ecore_dev.c | 32 drivers/net/qede/base/ecore_dev_api.h |3 +++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/net/qede/base/ecore.h b/drivers/net/qede/base/ecore.h index 5d79fdf..cf66c4c 100644 --- a/drivers/net/qede/base/ecore.h +++ b/drivers/net/qede/base/ecore.h @@ -870,6 +870,9 @@ struct ecore_dev { boolb_is_emul_full; #endif + /* Indicates whether this PF serves a storage target */ + boolb_is_target; + #ifdef CONFIG_ECORE_BINARY_FW /* @DPDK */ void*firmware; u64 fw_len; diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c index 6302abc..fdb62f2 100644 --- a/drivers/net/qede/base/ecore_dev.c +++ b/drivers/net/qede/base/ecore_dev.c @@ -3027,15 +3027,30 @@ static void ecore_hw_set_feat(struct ecore_hwfn *p_hwfn) FEAT_NUM(p_hwfn, ECORE_VF_L2_QUE)); } - if (ECORE_IS_FCOE_PERSONALITY(p_hwfn)) - feat_num[ECORE_FCOE_CQ] = - OSAL_MIN_T(u32, sb_cnt.cnt, RESC_NUM(p_hwfn, -ECORE_CMDQS_CQS)); + if (ECORE_IS_FCOE_PERSONALITY(p_hwfn) || + ECORE_IS_ISCSI_PERSONALITY(p_hwfn)) { + u32 *p_storage_feat = ECORE_IS_FCOE_PERSONALITY(p_hwfn) ? + &feat_num[ECORE_FCOE_CQ] : + &feat_num[ECORE_ISCSI_CQ]; + u32 limit = sb_cnt.cnt; + + /* The number of queues should not exceed the number of FP SBs. +* In storage target, the queues are divided into pairs of a CQ +* and a CmdQ, and each pair uses a single SB. The limit in +* this case should allow a max ratio of 2:1 instead of 1:1. +*/ + if (p_hwfn->p_dev->b_is_target) + limit *= 2; + *p_storage_feat = OSAL_MIN_T(u32, limit, +RESC_NUM(p_hwfn, ECORE_CMDQS_CQS)); - if (ECORE_IS_ISCSI_PERSONALITY(p_hwfn)) - feat_num[ECORE_ISCSI_CQ] = - OSAL_MIN_T(u32, sb_cnt.cnt, RESC_NUM(p_hwfn, -ECORE_CMDQS_CQS)); + /* @DPDK */ + /* The size of "cq_cmdq_sb_num_arr" in the fcoe/iscsi init +* ramrod is limited to "NUM_OF_GLOBAL_QUEUES / 2". +*/ + *p_storage_feat = OSAL_MIN_T(u32, *p_storage_feat, +(NUM_OF_GLOBAL_QUEUES / 2)); + } DP_VERBOSE(p_hwfn, ECORE_MSG_PROBE, "#PF_L2_QUEUE=%d VF_L2_QUEUES=%d #ROCE_CNQ=%d #FCOE_CQ=%d #ISCSI_CQ=%d #SB=%d\n", @@ -4327,6 +4342,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; + p_dev->b_is_target = p_params->b_is_target; if (p_params->b_relaxed_probe) p_params->p_relaxed_res = ECORE_HW_PREPARE_SUCCESS; diff --git a/drivers/net/qede/base/ecore_dev_api.h b/drivers/net/qede/base/ecore_dev_api.h index 02bacc2..7cba54c 100644 --- a/drivers/net/qede/base/ecore_dev_api.h +++ b/drivers/net/qede/base/ecore_dev_api.h @@ -271,6 +271,9 @@ struct ecore_hw_prepare_params { /* Enable/disable request by ecore client for pacing */ bool b_en_pacing; + + /* Indicates whether this PF serves a storage target */ + bool b_is_target; }; /** -- 1.7.10.3
[dpdk-dev] [PATCH 09/17] net/qede/base: use pointer for bytes len read
Signed-off-by: Rasesh Mody --- drivers/net/qede/base/ecore_mcp.c |4 ++-- drivers/net/qede/base/ecore_mcp_api.h |2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c index ea71d07..364c146 100644 --- a/drivers/net/qede/base/ecore_mcp.c +++ b/drivers/net/qede/base/ecore_mcp.c @@ -3053,7 +3053,7 @@ enum _ecore_status_t ecore_mcp_nvm_read(struct ecore_dev *p_dev, u32 addr, } enum _ecore_status_t ecore_mcp_phy_read(struct ecore_dev *p_dev, u32 cmd, - u32 addr, u8 *p_buf, u32 len) + u32 addr, u8 *p_buf, u32 *p_len) { struct ecore_hwfn *p_hwfn = ECORE_LEADING_HWFN(p_dev); struct ecore_ptt *p_ptt; @@ -3068,7 +3068,7 @@ enum _ecore_status_t ecore_mcp_phy_read(struct ecore_dev *p_dev, u32 cmd, (cmd == ECORE_PHY_CORE_READ) ? DRV_MSG_CODE_PHY_CORE_READ : DRV_MSG_CODE_PHY_RAW_READ, - addr, &resp, ¶m, &len, (u32 *)p_buf); + addr, &resp, ¶m, p_len, (u32 *)p_buf); if (rc != ECORE_SUCCESS) DP_NOTICE(p_dev, false, "MCP command rc = %d\n", rc); diff --git a/drivers/net/qede/base/ecore_mcp_api.h b/drivers/net/qede/base/ecore_mcp_api.h index 4098bae..7327074 100644 --- a/drivers/net/qede/base/ecore_mcp_api.h +++ b/drivers/net/qede/base/ecore_mcp_api.h @@ -943,7 +943,7 @@ enum _ecore_status_t ecore_mcp_nvm_del_file(struct ecore_dev *p_dev, * @return enum _ecore_status_t - ECORE_SUCCESS - operation was successful. */ enum _ecore_status_t ecore_mcp_phy_read(struct ecore_dev *p_dev, u32 cmd, - u32 addr, u8 *p_buf, u32 len); + u32 addr, u8 *p_buf, u32 *p_len); /** * @brief Read from nvm -- 1.7.10.3
[dpdk-dev] [PATCH 11/17] net/qede: fix flow director bug for IPv6 filter
From: Shahed Shaikh - PMD does not fill vtc_flow field of IPv6 header while constructing a packet for IPv6 filter. Hence filter was not getting applied properly. - IPv6 addresses got swapped while copying src and dst addresses. - Same issue with UDP and TCP port ids. Fixes: 622075356e8f ("net/qede: support ntuple and flow director filter") Cc: sta...@dpdk.org Signed-off-by: Shahed Shaikh --- drivers/net/qede/qede_filter.c | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/qede/qede_filter.c b/drivers/net/qede/qede_filter.c index b8460a0..4b709e6 100644 --- a/drivers/net/qede/qede_filter.c +++ b/drivers/net/qede/qede_filter.c @@ -121,7 +121,7 @@ #define QEDE_FDIR_IP_DEFAULT_VERSION_IHL (IP_VERSION | IP_HDRLEN) #define QEDE_FDIR_TCP_DEFAULT_DATAOFF (0x50) #define QEDE_FDIR_IPV4_DEF_TTL (64) - +#define QEDE_FDIR_IPV6_DEFAULT_VTC_FLOW(0x6000) /* Sum of length of header types of L2, L3, L4. * L2 : ether_hdr + vlan_hdr + vxlan_hdr * L3 : ipv6_hdr @@ -445,24 +445,28 @@ void qede_fdir_dealloc_resc(struct rte_eth_dev *eth_dev) ip6->proto = input->flow.ipv6_flow.proto ? input->flow.ipv6_flow.proto : next_proto[input->flow_type]; - rte_memcpy(&ip6->src_addr, &input->flow.ipv6_flow.dst_ip, + ip6->vtc_flow = + rte_cpu_to_be_32(QEDE_FDIR_IPV6_DEFAULT_VTC_FLOW); + + rte_memcpy(&ip6->src_addr, &input->flow.ipv6_flow.src_ip, IPV6_ADDR_LEN); - rte_memcpy(&ip6->dst_addr, &input->flow.ipv6_flow.src_ip, + rte_memcpy(&ip6->dst_addr, &input->flow.ipv6_flow.dst_ip, IPV6_ADDR_LEN); len += sizeof(struct ipv6_hdr); + params->ipv6 = true; raw_pkt = (uint8_t *)buff; /* UDP */ if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_UDP) { udp = (struct udp_hdr *)(raw_pkt + len); - udp->src_port = input->flow.udp6_flow.dst_port; - udp->dst_port = input->flow.udp6_flow.src_port; + udp->src_port = input->flow.udp6_flow.src_port; + udp->dst_port = input->flow.udp6_flow.dst_port; len += sizeof(struct udp_hdr); params->udp = true; } else { /* TCP */ tcp = (struct tcp_hdr *)(raw_pkt + len); - tcp->src_port = input->flow.tcp4_flow.src_port; - tcp->dst_port = input->flow.tcp4_flow.dst_port; + tcp->src_port = input->flow.tcp6_flow.src_port; + tcp->dst_port = input->flow.tcp6_flow.dst_port; tcp->data_off = QEDE_FDIR_TCP_DEFAULT_DATAOFF; len += sizeof(struct tcp_hdr); params->tcp = true; -- 1.7.10.3
[dpdk-dev] [PATCH 10/17] net/qede: reorganize filter code
From: Shahed Shaikh - rename qede_fdir.c to qede_filter.c - move all filter code to qede_filter.c Signed-off-by: Shahed Shaikh --- drivers/net/qede/Makefile |2 +- drivers/net/qede/qede_ethdev.c | 687 +--- drivers/net/qede/qede_ethdev.h | 25 +- drivers/net/qede/qede_fdir.c | 470 drivers/net/qede/qede_filter.c | 1147 5 files changed, 1172 insertions(+), 1159 deletions(-) delete mode 100644 drivers/net/qede/qede_fdir.c create mode 100644 drivers/net/qede/qede_filter.c diff --git a/drivers/net/qede/Makefile b/drivers/net/qede/Makefile index 488ca1d..2ecbd8d 100644 --- a/drivers/net/qede/Makefile +++ b/drivers/net/qede/Makefile @@ -105,6 +105,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += ecore_vf.c SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_ethdev.c SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_main.c SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_rxtx.c -SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_fdir.c +SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_filter.c include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index df52ea9..3a7c466 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -16,111 +16,6 @@ static const struct qed_eth_ops *qed_ops; #define QEDE_SP_TIMER_PERIOD 1 /* 100ms */ -/* VXLAN tunnel classification mapping */ -const struct _qede_udp_tunn_types { - uint16_t rte_filter_type; - enum ecore_filter_ucast_type qede_type; - enum ecore_tunn_clss qede_tunn_clss; - const char *string; -} qede_tunn_types[] = { - { - ETH_TUNNEL_FILTER_OMAC, - ECORE_FILTER_MAC, - ECORE_TUNN_CLSS_MAC_VLAN, - "outer-mac" - }, - { - ETH_TUNNEL_FILTER_TENID, - ECORE_FILTER_VNI, - ECORE_TUNN_CLSS_MAC_VNI, - "vni" - }, - { - ETH_TUNNEL_FILTER_IMAC, - ECORE_FILTER_INNER_MAC, - ECORE_TUNN_CLSS_INNER_MAC_VLAN, - "inner-mac" - }, - { - ETH_TUNNEL_FILTER_IVLAN, - ECORE_FILTER_INNER_VLAN, - ECORE_TUNN_CLSS_INNER_MAC_VLAN, - "inner-vlan" - }, - { - ETH_TUNNEL_FILTER_OMAC | ETH_TUNNEL_FILTER_TENID, - ECORE_FILTER_MAC_VNI_PAIR, - ECORE_TUNN_CLSS_MAC_VNI, - "outer-mac and vni" - }, - { - ETH_TUNNEL_FILTER_OMAC | ETH_TUNNEL_FILTER_IMAC, - ECORE_FILTER_UNUSED, - MAX_ECORE_TUNN_CLSS, - "outer-mac and inner-mac" - }, - { - ETH_TUNNEL_FILTER_OMAC | ETH_TUNNEL_FILTER_IVLAN, - ECORE_FILTER_UNUSED, - MAX_ECORE_TUNN_CLSS, - "outer-mac and inner-vlan" - }, - { - ETH_TUNNEL_FILTER_TENID | ETH_TUNNEL_FILTER_IMAC, - ECORE_FILTER_INNER_MAC_VNI_PAIR, - ECORE_TUNN_CLSS_INNER_MAC_VNI, - "vni and inner-mac", - }, - { - ETH_TUNNEL_FILTER_TENID | ETH_TUNNEL_FILTER_IVLAN, - ECORE_FILTER_UNUSED, - MAX_ECORE_TUNN_CLSS, - "vni and inner-vlan", - }, - { - ETH_TUNNEL_FILTER_IMAC | ETH_TUNNEL_FILTER_IVLAN, - ECORE_FILTER_INNER_PAIR, - ECORE_TUNN_CLSS_INNER_MAC_VLAN, - "inner-mac and inner-vlan", - }, - { - ETH_TUNNEL_FILTER_OIP, - ECORE_FILTER_UNUSED, - MAX_ECORE_TUNN_CLSS, - "outer-IP" - }, - { - ETH_TUNNEL_FILTER_IIP, - ECORE_FILTER_UNUSED, - MAX_ECORE_TUNN_CLSS, - "inner-IP" - }, - { - RTE_TUNNEL_FILTER_IMAC_IVLAN, - ECORE_FILTER_UNUSED, - MAX_ECORE_TUNN_CLSS, - "IMAC_IVLAN" - }, - { - RTE_TUNNEL_FILTER_IMAC_IVLAN_TENID, - ECORE_FILTER_UNUSED, - MAX_ECORE_TUNN_CLSS, - "IMAC_IVLAN_TENID" - }, - { - RTE_TUNNEL_FILTER_IMAC_TENID, - ECORE_FILTER_UNUSED, - MAX_ECORE_TUNN_CLSS, - "IMAC_TENID" - }, - { - RTE_TUNNEL_FILTER_OMAC_TENID_IMAC, - ECORE_FILTER_UNUSED, - MAX_ECORE_TUNN_CLSS, - "OMAC_TENID_IMAC" - }, -}; - struct rte_qede_xstats_name_off { char name[RTE_ETH_XSTATS_NAME_SIZE]; uint64_t offset; @@ -614,14 +509,6 @@ int qede_enable_tpa(struct rte_eth_dev *eth_dev, bool flg) return 0; } -static void qede_set_ucast_cmn_params(struct ecore_filter_ucast *ucast) -{ - memset(ucast, 0, sizeof(struct ecore_filter_ucast)); - ucast->is_rx_filter = t
[dpdk-dev] [PATCH 13/17] net/qede: add support for generic flow API
From: Shahed Shaikh - Add support for rte_flow_validate(), rte_flow_create() and rte_flow_destroy() APIs - This patch adds limited support for the flow items because of the limited filter profiles supported by HW. - Only 4 tuples - src and dst IP (v4 or v6) addresses and src and dst port IDs of TCP or UDP. - also, only redirect to queue action is supported. Signed-off-by: Shahed Shaikh --- drivers/net/qede/qede_ethdev.h |5 + drivers/net/qede/qede_filter.c | 334 +++- 2 files changed, 338 insertions(+), 1 deletion(-) diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h index 59828f8..8a9df98 100644 --- a/drivers/net/qede/qede_ethdev.h +++ b/drivers/net/qede/qede_ethdev.h @@ -184,6 +184,11 @@ struct qede_arfs_entry { SLIST_ENTRY(qede_arfs_entry) list; }; +/* Opaque handle for rte flow managed by PMD */ +struct rte_flow { + struct qede_arfs_entry entry; +}; + struct qede_arfs_info { struct ecore_arfs_config_params arfs; uint16_t filter_count; diff --git a/drivers/net/qede/qede_filter.c b/drivers/net/qede/qede_filter.c index bdf2885..5e6571c 100644 --- a/drivers/net/qede/qede_filter.c +++ b/drivers/net/qede/qede_filter.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "qede_ethdev.h" @@ -1159,6 +1160,327 @@ static void qede_get_ecore_tunn_params(uint32_t filter, uint32_t *type, return 0; } +static int +qede_flow_validate_attr(__attribute__((unused))struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + struct rte_flow_error *error) +{ + if (attr == NULL) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, NULL, + "NULL attribute"); + return -rte_errno; + } + + if (attr->group != 0) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_GROUP, attr, + "Groups are not supported"); + return -rte_errno; + } + + if (attr->priority != 0) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, attr, + "Priorities are not supported"); + return -rte_errno; + } + + if (attr->egress != 0) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, attr, + "Egress is not supported"); + return -rte_errno; + } + + if (attr->transfer != 0) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, attr, + "Transfer is not supported"); + return -rte_errno; + } + + if (attr->ingress == 0) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, attr, + "Only ingress is supported"); + return -rte_errno; + } + + return 0; +} + +static int +qede_flow_parse_pattern(__attribute__((unused))struct rte_eth_dev *dev, + const struct rte_flow_item pattern[], + struct rte_flow_error *error, + struct rte_flow *flow) +{ + bool l3 = false, l4 = false; + + if (pattern == NULL) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM_NUM, NULL, + "NULL pattern"); + return -rte_errno; + } + + for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) { + if (!pattern->spec) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + pattern, + "Item spec not defined"); + return -rte_errno; + } + + if (pattern->last) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + pattern, + "Item last not supported"); + return -rte_errno; + } + + if (pattern->mask) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + pattern, + "Item mask not supported"); + return -rte_errno; + } + + /* Below validation is o
[dpdk-dev] [PATCH 14/17] net/qede: fix Rx buffer size calculation
From: Shahed Shaikh - HW does not include CRC in received frame when passed to host, so no need to consider CRC length while calculating Rx buffer size. - In scattered Rx mode, driver may allocate Rx buffer larger than the size of mbuf because it tries to adjust the buffer size to cache line size by ceiling it. Fix this by flooring the size instead of ceiling. - Consider the rule imposed by HW regarding the minimum size of Rx buffer in scattered Rx mode - (MTU + Maximum L2 Header Size + 2) / ETH_RX_MAX_BUFF_PER_PKT Fixes: f6033f2497e7 ("net/qede: fix minimum buffer size and scatter Rx check") CC: sta...@dpdk.org Signed-off-by: Shahed Shaikh --- drivers/net/qede/qede_ethdev.c | 28 +-- drivers/net/qede/qede_rxtx.c | 59 +++- drivers/net/qede/qede_rxtx.h | 15 -- 3 files changed, 78 insertions(+), 24 deletions(-) diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index d5e162c..259eb45 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -1210,7 +1210,7 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev) if (rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) eth_dev->data->mtu = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len - - ETHER_HDR_LEN - ETHER_CRC_LEN; + ETHER_HDR_LEN - QEDE_ETH_OVERHEAD; if (rxmode->offloads & DEV_RX_OFFLOAD_SCATTER) eth_dev->data->scattered_rx = 1; @@ -2226,19 +2226,18 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) struct qede_fastpath *fp; uint32_t max_rx_pkt_len; uint32_t frame_size; - uint16_t rx_buf_size; uint16_t bufsz; bool restart = false; - int i; + int i, rc; PMD_INIT_FUNC_TRACE(edev); qede_dev_info_get(dev, &dev_info); - max_rx_pkt_len = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; - frame_size = max_rx_pkt_len + QEDE_ETH_OVERHEAD; + max_rx_pkt_len = mtu + QEDE_MAX_ETHER_HDR_LEN; + frame_size = max_rx_pkt_len; if ((mtu < ETHER_MIN_MTU) || (frame_size > dev_info.max_rx_pktlen)) { DP_ERR(edev, "MTU %u out of range, %u is maximum allowable\n", mtu, dev_info.max_rx_pktlen - ETHER_HDR_LEN - - ETHER_CRC_LEN - QEDE_ETH_OVERHEAD); + QEDE_ETH_OVERHEAD); return -EINVAL; } if (!dev->data->scattered_rx && @@ -2266,14 +2265,15 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) if (fp->rxq != NULL) { bufsz = (uint16_t)rte_pktmbuf_data_room_size( fp->rxq->mb_pool) - RTE_PKTMBUF_HEADROOM; - if (dev->data->scattered_rx) - rx_buf_size = bufsz + ETHER_HDR_LEN + - ETHER_CRC_LEN + QEDE_ETH_OVERHEAD; - else - rx_buf_size = frame_size; - rx_buf_size = QEDE_CEIL_TO_CACHE_LINE_SIZE(rx_buf_size); - fp->rxq->rx_buf_size = rx_buf_size; - DP_INFO(edev, "RX buffer size %u\n", rx_buf_size); + /* cache align the mbuf size to simplfy rx_buf_size +* calculation +*/ + bufsz = QEDE_FLOOR_TO_CACHE_LINE_SIZE(bufsz); + rc = qede_calc_rx_buf_size(dev, bufsz, frame_size); + if (rc < 0) + return rc; + + fp->rxq->rx_buf_size = rc; } } if (max_rx_pkt_len > ETHER_MAX_LEN) diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c index 0f157de..675c0a0 100644 --- a/drivers/net/qede/qede_rxtx.c +++ b/drivers/net/qede/qede_rxtx.c @@ -35,6 +35,49 @@ static inline int qede_alloc_rx_buffer(struct qede_rx_queue *rxq) return 0; } +/* Criterias for calculating Rx buffer size - + * 1) rx_buf_size should not exceed the size of mbuf + * 2) In scattered_rx mode - minimum rx_buf_size should be + *(MTU + Maximum L2 Header Size + 2) / ETH_RX_MAX_BUFF_PER_PKT + * 3) In regular mode - minimum rx_buf_size should be + *(MTU + Maximum L2 Header Size + 2) + *In above cases +2 corrosponds to 2 bytes padding in front of L2 + *header. + * 4) rx_buf_size should be cacheline-size aligned. So considering + *criteria 1, we need to adjust the size to floor instead of ceil, + *so that we don't exceed mbuf size while ceiling rx_buf_size. + */ +int +qede_calc_rx_buf_size(struct rte_eth_dev *dev, uint16_t mbufsz, + uint16_t max_frame_size) +{ + struct qede_dev *qdev = QEDE_INIT_QDEV(dev); + struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); + int rx_buf
[dpdk-dev] [PATCH 16/17] net/qede/base: fix MFW FLR flow bug
From: Shahed Shaikh Management firmware does not properly clean IGU block in PF FLR flow which may result in undelivered attentions for link events from default status block. Add a workaround in PMD to execute extra IGU cleanup right after PF FLR is done. Fixes: 9e2f08a4ad5f ("net/qede/base: add request for PF FLR before load request") Cc: sta...@dpdk.org Signed-off-by: Shahed Shaikh --- drivers/net/qede/base/ecore_dev.c |7 +++ drivers/net/qede/base/ecore_int.c | 32 drivers/net/qede/base/ecore_int.h |1 + drivers/net/qede/base/mcp_public.h |2 ++ drivers/net/qede/base/reg_addr.h | 15 +++ 5 files changed, 57 insertions(+) diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c index fdb62f2..d91fe27 100644 --- a/drivers/net/qede/base/ecore_dev.c +++ b/drivers/net/qede/base/ecore_dev.c @@ -4272,6 +4272,13 @@ void ecore_prepare_hibernate(struct ecore_dev *p_dev) rc = ecore_mcp_initiate_pf_flr(p_hwfn, p_hwfn->p_main_ptt); if (rc != ECORE_SUCCESS) DP_NOTICE(p_hwfn, false, "Failed to initiate PF FLR\n"); + + /* Workaround for MFW issue where PF FLR does not cleanup +* IGU block +*/ + if (!(p_hwfn->mcp_info->capabilities & + FW_MB_PARAM_FEATURE_SUPPORT_IGU_CLEANUP)) + ecore_pf_flr_igu_cleanup(p_hwfn); } /* Check if mdump logs/data are present and update the epoch value */ diff --git a/drivers/net/qede/base/ecore_int.c b/drivers/net/qede/base/ecore_int.c index 4c271d3..d41107d 100644 --- a/drivers/net/qede/base/ecore_int.c +++ b/drivers/net/qede/base/ecore_int.c @@ -2681,3 +2681,35 @@ enum _ecore_status_t ecore_int_get_sb_dbg(struct ecore_hwfn *p_hwfn, return ECORE_SUCCESS; } + +void ecore_pf_flr_igu_cleanup(struct ecore_hwfn *p_hwfn) +{ + struct ecore_ptt *p_ptt = p_hwfn->p_main_ptt; + struct ecore_ptt *p_dpc_ptt = ecore_get_reserved_ptt(p_hwfn, +RESERVED_PTT_DPC); + int i; + + /* Do not reorder the following cleanup sequence */ + /* Ack all attentions */ + ecore_wr(p_hwfn, p_ptt, IGU_REG_ATTENTION_ACK_BITS, 0xfff); + + /* Clear driver attention */ + ecore_wr(p_hwfn, p_dpc_ptt, + ((p_hwfn->rel_pf_id << 3) + MISC_REG_AEU_GENERAL_ATTN_0), 0); + + /* Clear per-PF IGU registers to restore them as if the IGU +* was reset for this PF +*/ + ecore_wr(p_hwfn, p_ptt, IGU_REG_LEADING_EDGE_LATCH, 0); + ecore_wr(p_hwfn, p_ptt, IGU_REG_TRAILING_EDGE_LATCH, 0); + ecore_wr(p_hwfn, p_ptt, IGU_REG_PF_CONFIGURATION, 0); + + /* Execute IGU clean up*/ + ecore_wr(p_hwfn, p_ptt, IGU_REG_PF_FUNCTIONAL_CLEANUP, 1); + + /* Clear Stats */ + ecore_wr(p_hwfn, p_ptt, IGU_REG_STATISTIC_NUM_OF_INTA_ASSERTED, 0); + + for (i = 0; i < IGU_REG_PBA_STS_PF_SIZE; i++) + ecore_wr(p_hwfn, p_ptt, IGU_REG_PBA_STS_PF + i * 4, 0); +} diff --git a/drivers/net/qede/base/ecore_int.h b/drivers/net/qede/base/ecore_int.h index 041240d..ff2310c 100644 --- a/drivers/net/qede/base/ecore_int.h +++ b/drivers/net/qede/base/ecore_int.h @@ -256,5 +256,6 @@ enum _ecore_status_t ecore_int_set_timer_res(struct ecore_hwfn *p_hwfn, enum _ecore_status_t ecore_pglueb_rbc_attn_handler(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, bool is_hw_init); +void ecore_pf_flr_igu_cleanup(struct ecore_hwfn *p_hwfn); #endif /* __ECORE_INT_H__ */ diff --git a/drivers/net/qede/base/mcp_public.h b/drivers/net/qede/base/mcp_public.h index e9f3350..2ee8ab5 100644 --- a/drivers/net/qede/base/mcp_public.h +++ b/drivers/net/qede/base/mcp_public.h @@ -1797,6 +1797,8 @@ struct public_drv_mb { #define FW_MB_PARAM_FEATURE_SUPPORT_EEE 0x0002 /* MFW supports DRV_LOAD Timeout */ #define FW_MB_PARAM_FEATURE_SUPPORT_DRV_LOAD_TO 0x0004 +/* MFW support complete IGU cleanup upon FLR */ +#define FW_MB_PARAM_FEATURE_SUPPORT_IGU_CLEANUP0x0080 /* MFW supports virtual link */ #define FW_MB_PARAM_FEATURE_SUPPORT_VLINK 0x0001 diff --git a/drivers/net/qede/base/reg_addr.h b/drivers/net/qede/base/reg_addr.h index 7ed26fc..b82ccc1 100644 --- a/drivers/net/qede/base/reg_addr.h +++ b/drivers/net/qede/base/reg_addr.h @@ -322,6 +322,21 @@ 0x180820UL #define IGU_REG_ATTN_MSG_ADDR_H \ 0x180824UL +#define IGU_REG_LEADING_EDGE_LATCH \ + 0x18082cUL +#define IGU_REG_TRAILING_EDGE_LATCH \ + 0x180830UL +#define IGU_REG_ATTENTION_ACK_BITS \ + 0x180838UL +#define IGU_REG_PBA_STS_PF \ + 0x180d20UL +#define IGU_REG_PF_FUNCTIONAL_CLEANUP \ + 0x181210UL +#define IGU_REG_STATISTIC_NUM_OF_INTA_ASSERTED \ + 0x18042cUL +#define I
[dpdk-dev] [PATCH 12/17] net/qede: refactor fdir code into generic aRFS
From: Shahed Shaikh - In order to prepare the base for RTE FLOW support, convert common code used for flow director support into common aRFS code. Signed-off-by: Shahed Shaikh --- drivers/net/qede/base/ecore_l2.c | 26 ++- drivers/net/qede/base/ecore_l2_api.h | 11 +- drivers/net/qede/qede_ethdev.c |2 +- drivers/net/qede/qede_ethdev.h | 35 +++- drivers/net/qede/qede_filter.c | 291 +- 5 files changed, 240 insertions(+), 125 deletions(-) diff --git a/drivers/net/qede/base/ecore_l2.c b/drivers/net/qede/base/ecore_l2.c index d71f461..ca4d901 100644 --- a/drivers/net/qede/base/ecore_l2.c +++ b/drivers/net/qede/base/ecore_l2.c @@ -2084,6 +2084,24 @@ void ecore_reset_vport_stats(struct ecore_dev *p_dev) } } +static enum gft_profile_type +ecore_arfs_mode_to_hsi(enum ecore_filter_config_mode mode) +{ + if (mode == ECORE_FILTER_CONFIG_MODE_5_TUPLE) + return GFT_PROFILE_TYPE_4_TUPLE; + + if (mode == ECORE_FILTER_CONFIG_MODE_IP_DEST) + return GFT_PROFILE_TYPE_IP_DST_ADDR; + + if (mode == ECORE_FILTER_CONFIG_MODE_TUNN_TYPE) + return GFT_PROFILE_TYPE_TUNNEL_TYPE; + + if (mode == ECORE_FILTER_CONFIG_MODE_IP_SRC) + return GFT_PROFILE_TYPE_IP_SRC_ADDR; + + return GFT_PROFILE_TYPE_L4_DST_PORT; +} + void ecore_arfs_mode_configure(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, struct ecore_arfs_config_params *p_cfg_params) @@ -2091,13 +2109,13 @@ void ecore_arfs_mode_configure(struct ecore_hwfn *p_hwfn, if (OSAL_TEST_BIT(ECORE_MF_DISABLE_ARFS, &p_hwfn->p_dev->mf_bits)) return; - if (p_cfg_params->arfs_enable) { + if (p_cfg_params->mode != ECORE_FILTER_CONFIG_MODE_DISABLE) { ecore_gft_config(p_hwfn, p_ptt, p_hwfn->rel_pf_id, p_cfg_params->tcp, p_cfg_params->udp, p_cfg_params->ipv4, p_cfg_params->ipv6, -GFT_PROFILE_TYPE_4_TUPLE); +ecore_arfs_mode_to_hsi(p_cfg_params->mode)); DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "tcp = %s, udp = %s, ipv4 = %s, ipv6 =%s\n", p_cfg_params->tcp ? "Enable" : "Disable", @@ -2107,8 +2125,8 @@ void ecore_arfs_mode_configure(struct ecore_hwfn *p_hwfn, } else { ecore_gft_disable(p_hwfn, p_ptt, p_hwfn->rel_pf_id); } - DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "Configured ARFS mode : %s\n", - p_cfg_params->arfs_enable ? "Enable" : "Disable"); + DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "Configured ARFS mode : %d\n", + (int)p_cfg_params->mode); } enum _ecore_status_t diff --git a/drivers/net/qede/base/ecore_l2_api.h b/drivers/net/qede/base/ecore_l2_api.h index 575b9e3..85034e6 100644 --- a/drivers/net/qede/base/ecore_l2_api.h +++ b/drivers/net/qede/base/ecore_l2_api.h @@ -139,12 +139,21 @@ struct ecore_filter_accept_flags { #define ECORE_ACCEPT_BCAST 0x20 }; +enum ecore_filter_config_mode { + ECORE_FILTER_CONFIG_MODE_DISABLE, + ECORE_FILTER_CONFIG_MODE_5_TUPLE, + ECORE_FILTER_CONFIG_MODE_L4_PORT, + ECORE_FILTER_CONFIG_MODE_IP_DEST, + ECORE_FILTER_CONFIG_MODE_TUNN_TYPE, + ECORE_FILTER_CONFIG_MODE_IP_SRC, +}; + struct ecore_arfs_config_params { bool tcp; bool udp; bool ipv4; bool ipv6; - bool arfs_enable; /* Enable or disable arfs mode */ + enum ecore_filter_config_mode mode; }; /* Add / remove / move / remove-all unicast MAC-VLAN filters. diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index 3a7c466..d5e162c 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -2576,7 +2576,7 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf) adapter->num_tx_queues = 0; adapter->num_rx_queues = 0; - SLIST_INIT(&adapter->fdir_info.fdir_list_head); + SLIST_INIT(&adapter->arfs_info.arfs_list_head); SLIST_INIT(&adapter->vlan_list_head); SLIST_INIT(&adapter->uc_list_head); SLIST_INIT(&adapter->mc_list_head); diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h index d54f19b..59828f8 100644 --- a/drivers/net/qede/qede_ethdev.h +++ b/drivers/net/qede/qede_ethdev.h @@ -151,18 +151,43 @@ struct qede_ucast_entry { SLIST_ENTRY(qede_ucast_entry) list; }; -struct qede_fdir_entry { +#ifndef IPV6_ADDR_LEN +#define IPV6_ADDR_LEN (16) +#endif + +struct qede_arfs_tuple { + union { + uint32_t src_ipv4; + uint8_t src_ipv6[IPV6_ADDR_LEN]; + }; + + union { + uint32_t dst_ipv
[dpdk-dev] [PATCH 17/17] net/qede: add support for dev reset
From: Shahed Shaikh Implement eth_dev_ops->dev_reset callback. Signed-off-by: Shahed Shaikh --- drivers/net/qede/qede_ethdev.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index 322400c..36a51f6 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -14,6 +14,9 @@ int qede_logtype_driver; static const struct qed_eth_ops *qed_ops; +static int qede_eth_dev_uninit(struct rte_eth_dev *eth_dev); +static int qede_eth_dev_init(struct rte_eth_dev *eth_dev); + #define QEDE_SP_TIMER_PERIOD 1 /* 100ms */ struct rte_qede_xstats_name_off { @@ -2295,6 +2298,18 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) return 0; } +static int +qede_dev_reset(struct rte_eth_dev *dev) +{ + int ret; + + ret = qede_eth_dev_uninit(dev); + if (ret) + return ret; + + return qede_eth_dev_init(dev); +} + static const struct eth_dev_ops qede_eth_dev_ops = { .dev_configure = qede_dev_configure, .dev_infos_get = qede_dev_info_get, @@ -2304,6 +2319,7 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) .tx_queue_setup = qede_tx_queue_setup, .tx_queue_release = qede_tx_queue_release, .dev_start = qede_dev_start, + .dev_reset = qede_dev_reset, .dev_set_link_up = qede_dev_set_link_up, .dev_set_link_down = qede_dev_set_link_down, .link_update = qede_link_update, @@ -2346,6 +2362,7 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) .tx_queue_setup = qede_tx_queue_setup, .tx_queue_release = qede_tx_queue_release, .dev_start = qede_dev_start, + .dev_reset = qede_dev_reset, .dev_set_link_up = qede_dev_set_link_up, .dev_set_link_down = qede_dev_set_link_down, .link_update = qede_link_update, -- 1.7.10.3
[dpdk-dev] [PATCH 15/17] net/qede: add support for Rx descriptor status
From: Shahed Shaikh This patch implement eth_dev_ops->rx_descriptor_status callback. Walk through receive completion ring to calculate receive descriptors used by firmware and then provide the status of offset accordingly. Signed-off-by: Shahed Shaikh --- drivers/net/qede/qede_ethdev.c |2 + drivers/net/qede/qede_rxtx.c | 81 drivers/net/qede/qede_rxtx.h |2 + 3 files changed, 85 insertions(+) diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index 259eb45..322400c 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -2300,6 +2300,7 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) .dev_infos_get = qede_dev_info_get, .rx_queue_setup = qede_rx_queue_setup, .rx_queue_release = qede_rx_queue_release, + .rx_descriptor_status = qede_rx_descriptor_status, .tx_queue_setup = qede_tx_queue_setup, .tx_queue_release = qede_tx_queue_release, .dev_start = qede_dev_start, @@ -2341,6 +2342,7 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) .dev_infos_get = qede_dev_info_get, .rx_queue_setup = qede_rx_queue_setup, .rx_queue_release = qede_rx_queue_release, + .rx_descriptor_status = qede_rx_descriptor_status, .tx_queue_setup = qede_tx_queue_setup, .tx_queue_release = qede_tx_queue_release, .dev_start = qede_dev_start, diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c index 675c0a0..8a4772f 100644 --- a/drivers/net/qede/qede_rxtx.c +++ b/drivers/net/qede/qede_rxtx.c @@ -2151,3 +2151,84 @@ static inline uint32_t qede_rx_cqe_to_tunn_pkt_type(uint16_t flags) { return 0; } + + +/* this function does a fake walk through over completion queue + * to calculate number of BDs used by HW. + * At the end, it restores the state of completion queue. + */ +static uint16_t +qede_parse_fp_cqe(struct qede_rx_queue *rxq) +{ + uint16_t hw_comp_cons, sw_comp_cons, bd_count = 0; + union eth_rx_cqe *cqe, *orig_cqe = NULL; + + hw_comp_cons = rte_le_to_cpu_16(*rxq->hw_cons_ptr); + sw_comp_cons = ecore_chain_get_cons_idx(&rxq->rx_comp_ring); + + if (hw_comp_cons == sw_comp_cons) + return 0; + + /* Get the CQE from the completion ring */ + cqe = (union eth_rx_cqe *)ecore_chain_consume(&rxq->rx_comp_ring); + orig_cqe = cqe; + + while (sw_comp_cons != hw_comp_cons) { + switch (cqe->fast_path_regular.type) { + case ETH_RX_CQE_TYPE_REGULAR: + bd_count += cqe->fast_path_regular.bd_num; + break; + case ETH_RX_CQE_TYPE_TPA_END: + bd_count += cqe->fast_path_tpa_end.num_of_bds; + break; + default: + break; + } + + cqe = + (union eth_rx_cqe *)ecore_chain_consume(&rxq->rx_comp_ring); + sw_comp_cons = ecore_chain_get_cons_idx(&rxq->rx_comp_ring); + } + + /* revert comp_ring to original state */ + ecore_chain_set_cons(&rxq->rx_comp_ring, sw_comp_cons, orig_cqe); + + return bd_count; +} + +int +qede_rx_descriptor_status(void *p_rxq, uint16_t offset) +{ + uint16_t hw_bd_cons, sw_bd_cons, sw_bd_prod; + uint16_t produced, consumed; + struct qede_rx_queue *rxq = p_rxq; + + if (offset > rxq->nb_rx_desc) + return -EINVAL; + + sw_bd_cons = ecore_chain_get_cons_idx(&rxq->rx_bd_ring); + sw_bd_prod = ecore_chain_get_prod_idx(&rxq->rx_bd_ring); + + /* find BDs used by HW from completion queue elements */ + hw_bd_cons = sw_bd_cons + qede_parse_fp_cqe(rxq); + + if (hw_bd_cons < sw_bd_cons) + /* wraparound case */ + consumed = (0x - sw_bd_cons) + hw_bd_cons; + else + consumed = hw_bd_cons - sw_bd_cons; + + if (offset <= consumed) + return RTE_ETH_RX_DESC_DONE; + + if (sw_bd_prod < sw_bd_cons) + /* wraparound case */ + produced = (0x - sw_bd_cons) + sw_bd_prod; + else + produced = sw_bd_prod - sw_bd_cons; + + if (offset <= produced) + return RTE_ETH_RX_DESC_AVAIL; + + return RTE_ETH_RX_DESC_UNAVAIL; +} diff --git a/drivers/net/qede/qede_rxtx.h b/drivers/net/qede/qede_rxtx.h index 8bd8d1c..d3a41e9 100644 --- a/drivers/net/qede/qede_rxtx.h +++ b/drivers/net/qede/qede_rxtx.h @@ -276,6 +276,8 @@ uint16_t qede_rxtx_pkts_dummy(void *p_rxq, void qede_stop_queues(struct rte_eth_dev *eth_dev); int qede_calc_rx_buf_size(struct rte_eth_dev *dev, uint16_t mbufsz, uint16_t max_frame_size); +int +qede_rx_descriptor_status(void *rxq, uint16_t offset); /* Fastpath resource alloc/dealloc helpers */ int qede_alloc_fp_resc(struct qede_dev *qdev);