Skip to content

Commit

Permalink
qede: add SRIOV support
Browse files Browse the repository at this point in the history
This patch adds following SRIOV features to qede PMD:
 - VF configuration
 - VF intialization/de-initialization
 - VF PF communications channel
 - statistics capture and query

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
  • Loading branch information
Rasesh Mody authored and bruce-richardson committed May 6, 2016
1 parent 5cdd769 commit 86a2265
Show file tree
Hide file tree
Showing 22 changed files with 7,969 additions and 96 deletions.
2 changes: 2 additions & 0 deletions drivers/net/qede/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += base/ecore_init_ops.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += base/ecore_mcp.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += base/ecore_int.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += base/bcm_osal.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += base/ecore_sriov.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += base/ecore_vf.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_ethdev.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_eth_if.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_main.c
Expand Down
9 changes: 9 additions & 0 deletions drivers/net/qede/base/bcm_osal.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "bcm_osal.h"
#include "ecore.h"
#include "ecore_hw.h"
#include "ecore_iov_api.h"

unsigned long qede_log2_align(unsigned long n)
{
Expand Down Expand Up @@ -81,6 +82,14 @@ inline u32 qede_find_first_zero_bit(unsigned long *addr, u32 limit)
return (i == nwords) ? limit : i * OSAL_BITS_PER_UL + qede_ffz(addr[i]);
}

void qede_vf_fill_driver_data(struct ecore_hwfn *hwfn,
__rte_unused struct vf_pf_resc_request *resc_req,
struct ecore_vf_acquire_sw_info *vf_sw_info)
{
vf_sw_info->os_type = VFPF_ACQUIRE_OS_LINUX_USERSPACE;
vf_sw_info->override_fw_version = 1;
}

void *osal_dma_alloc_coherent(struct ecore_dev *p_dev,
dma_addr_t *phys, size_t size)
{
Expand Down
10 changes: 8 additions & 2 deletions drivers/net/qede/base/bcm_osal.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
/* Forward declaration */
struct ecore_dev;
struct ecore_hwfn;
struct ecore_vf_acquire_sw_info;
struct vf_pf_resc_request;
void qed_link_update(struct ecore_hwfn *hwfn);

#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
#undef __BIG_ENDIAN
Expand Down Expand Up @@ -302,7 +305,7 @@ u32 qede_find_first_zero_bit(unsigned long *, u32);
#define OSAL_BUILD_BUG_ON(cond) nothing
#define ETH_ALEN ETHER_ADDR_LEN

#define OSAL_LINK_UPDATE(hwfn) nothing
#define OSAL_LINK_UPDATE(hwfn) qed_link_update(hwfn)

/* SR-IOV channel */

Expand All @@ -315,12 +318,15 @@ u32 qede_find_first_zero_bit(unsigned long *, u32);
#define OSAL_IOV_VF_ACQUIRE(hwfn, vfid) 0
#define OSAL_IOV_VF_CLEANUP(hwfn, vfid) nothing
#define OSAL_IOV_VF_VPORT_UPDATE(hwfn, vfid, p_params, p_mask) 0
#define OSAL_VF_FILL_ACQUIRE_RESC_REQ(_dev_p, _resc_req, _os_info) nothing
#define OSAL_VF_UPDATE_ACQUIRE_RESC_RESP(_dev_p, _resc_resp) 0
#define OSAL_IOV_GET_OS_TYPE() 0

u32 qede_unzip_data(struct ecore_hwfn *p_hwfn, u32 input_len,
u8 *input_buf, u32 max_size, u8 *unzip_buf);
void qede_vf_fill_driver_data(struct ecore_hwfn *, struct vf_pf_resc_request *,
struct ecore_vf_acquire_sw_info *);
#define OSAL_VF_FILL_ACQUIRE_RESC_REQ(_dev_p, _resc_req, _os_info) \
qede_vf_fill_driver_data(_dev_p, _resc_req, _os_info)

#define OSAL_UNZIP_DATA(p_hwfn, input_len, buf, max_size, unzip_buf) \
qede_unzip_data(p_hwfn, input_len, buf, max_size, unzip_buf)
Expand Down
10 changes: 10 additions & 0 deletions drivers/net/qede/base/ecore.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ enum ecore_nvm_cmd {
#ifndef LINUX_REMOVE
#if !defined(CONFIG_ECORE_L2)
#define CONFIG_ECORE_L2
#define CONFIG_ECORE_SRIOV
#endif
#endif

Expand Down Expand Up @@ -79,6 +80,15 @@ static OSAL_INLINE u32 DB_ADDR(u32 cid, u32 DEMS)
return db_addr;
}

/* @DPDK: This is a backport from latest ecore for TSS fix */
static OSAL_INLINE u32 DB_ADDR_VF(u32 cid, u32 DEMS)
{
u32 db_addr = FIELD_VALUE(DB_LEGACY_ADDR_DEMS, DEMS) |
FIELD_VALUE(DB_LEGACY_ADDR_ICID, cid);

return db_addr;
}

#define ALIGNED_TYPE_SIZE(type_name, p_hwfn) \
((sizeof(type_name) + (u32)(1 << (p_hwfn->p_dev->cache_shift)) - 1) & \
~((1 << (p_hwfn->p_dev->cache_shift)) - 1))
Expand Down
99 changes: 88 additions & 11 deletions drivers/net/qede/base/ecore_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "ecore_init_fw_funcs.h"
#include "ecore_sp_commands.h"
#include "ecore_dev_api.h"
#include "ecore_sriov.h"
#include "ecore_vf.h"
#include "ecore_mcp.h"
#include "ecore_hw_defs.h"
#include "mcp_public.h"
Expand Down Expand Up @@ -126,6 +128,9 @@ void ecore_resc_free(struct ecore_dev *p_dev)
{
int i;

if (IS_VF(p_dev))
return;

OSAL_FREE(p_dev, p_dev->fw_data);
p_dev->fw_data = OSAL_NULL;

Expand All @@ -149,6 +154,7 @@ void ecore_resc_free(struct ecore_dev *p_dev)
ecore_eq_free(p_hwfn, p_hwfn->p_eq);
ecore_consq_free(p_hwfn, p_hwfn->p_consq);
ecore_int_free(p_hwfn);
ecore_iov_free(p_hwfn);
ecore_dmae_info_free(p_hwfn);
/* @@@TBD Flush work-queue ? */
}
Expand All @@ -161,7 +167,11 @@ static enum _ecore_status_t ecore_init_qm_info(struct ecore_hwfn *p_hwfn,
struct ecore_qm_info *qm_info = &p_hwfn->qm_info;
struct init_qm_port_params *p_qm_port;
u16 num_pqs, multi_cos_tcs = 1;
#ifdef CONFIG_ECORE_SRIOV
u16 num_vfs = p_hwfn->p_dev->sriov_info.total_vfs;
#else
u16 num_vfs = 0;
#endif

OSAL_MEM_ZERO(qm_info, sizeof(*qm_info));

Expand Down Expand Up @@ -363,6 +373,9 @@ enum _ecore_status_t ecore_resc_alloc(struct ecore_dev *p_dev)
struct ecore_eq *p_eq;
int i;

if (IS_VF(p_dev))
return rc;

p_dev->fw_data = OSAL_ZALLOC(p_dev, GFP_KERNEL,
sizeof(struct ecore_fw_data));
if (!p_dev->fw_data)
Expand Down Expand Up @@ -440,6 +453,10 @@ enum _ecore_status_t ecore_resc_alloc(struct ecore_dev *p_dev)
if (rc)
goto alloc_err;

rc = ecore_iov_alloc(p_hwfn);
if (rc)
goto alloc_err;

/* EQ */
p_eq = ecore_eq_alloc(p_hwfn, 256);
if (!p_eq)
Expand Down Expand Up @@ -481,6 +498,9 @@ void ecore_resc_setup(struct ecore_dev *p_dev)
{
int i;

if (IS_VF(p_dev))
return;

for_each_hwfn(p_dev, i) {
struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];

Expand All @@ -496,6 +516,8 @@ void ecore_resc_setup(struct ecore_dev *p_dev)
p_hwfn->mcp_info->mfw_mb_length);

ecore_int_setup(p_hwfn, p_hwfn->p_main_ptt);

ecore_iov_setup(p_hwfn, p_hwfn->p_main_ptt);
}
}

Expand Down Expand Up @@ -1250,13 +1272,22 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
u32 load_code, param;
int i, j;

rc = ecore_init_fw_data(p_dev, bin_fw_data);
if (rc != ECORE_SUCCESS)
return rc;
if (IS_PF(p_dev)) {
rc = ecore_init_fw_data(p_dev, bin_fw_data);
if (rc != ECORE_SUCCESS)
return rc;
}

for_each_hwfn(p_dev, i) {
struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];

if (IS_VF(p_dev)) {
rc = ecore_vf_pf_init(p_hwfn);
if (rc)
return rc;
continue;
}

/* Enable DMAE in PXP */
rc = ecore_change_pci_hwfn(p_hwfn, p_hwfn->p_main_ptt, true);

Expand Down Expand Up @@ -1416,6 +1447,11 @@ enum _ecore_status_t ecore_hw_stop(struct ecore_dev *p_dev)

DP_VERBOSE(p_hwfn, ECORE_MSG_IFDOWN, "Stopping hw/fw\n");

if (IS_VF(p_dev)) {
ecore_vf_pf_int_cleanup(p_hwfn);
continue;
}

/* mark the hw as uninitialized... */
p_hwfn->hw_init_done = false;

Expand Down Expand Up @@ -1454,14 +1490,16 @@ enum _ecore_status_t ecore_hw_stop(struct ecore_dev *p_dev)
OSAL_MSLEEP(1);
}

/* Disable DMAE in PXP - in CMT, this should only be done for
* first hw-function, and only after all transactions have
* stopped for all active hw-functions.
*/
t_rc = ecore_change_pci_hwfn(&p_dev->hwfns[0],
p_dev->hwfns[0].p_main_ptt, false);
if (t_rc != ECORE_SUCCESS)
rc = t_rc;
if (IS_PF(p_dev)) {
/* Disable DMAE in PXP - in CMT, this should only be done for
* first hw-function, and only after all transactions have
* stopped for all active hw-functions.
*/
t_rc = ecore_change_pci_hwfn(&p_dev->hwfns[0],
p_dev->hwfns[0].p_main_ptt, false);
if (t_rc != ECORE_SUCCESS)
rc = t_rc;
}

return rc;
}
Expand All @@ -1474,6 +1512,11 @@ void ecore_hw_stop_fastpath(struct ecore_dev *p_dev)
struct ecore_hwfn *p_hwfn = &p_dev->hwfns[j];
struct ecore_ptt *p_ptt = p_hwfn->p_main_ptt;

if (IS_VF(p_dev)) {
ecore_vf_pf_int_cleanup(p_hwfn);
continue;
}

DP_VERBOSE(p_hwfn, ECORE_MSG_IFDOWN,
"Shutting down the fastpath\n");

Expand All @@ -1499,6 +1542,9 @@ void ecore_hw_start_fastpath(struct ecore_hwfn *p_hwfn)
{
struct ecore_ptt *p_ptt = p_hwfn->p_main_ptt;

if (IS_VF(p_hwfn->p_dev))
return;

/* Re-open incoming traffic */
ecore_wr(p_hwfn, p_hwfn->p_main_ptt,
NIG_REG_RX_LLH_BRB_GATE_DNTFWD_PERPF, 0x0);
Expand Down Expand Up @@ -1528,6 +1574,13 @@ enum _ecore_status_t ecore_hw_reset(struct ecore_dev *p_dev)
for_each_hwfn(p_dev, i) {
struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];

if (IS_VF(p_dev)) {
rc = ecore_vf_pf_reset(p_hwfn);
if (rc)
return rc;
continue;
}

DP_VERBOSE(p_hwfn, ECORE_MSG_IFDOWN, "Resetting hw/fw\n");

/* Check for incorrect states */
Expand Down Expand Up @@ -1657,7 +1710,11 @@ static enum _ecore_status_t ecore_hw_get_resc(struct ecore_hwfn *p_hwfn)

OSAL_MEM_ZERO(&sb_cnt_info, sizeof(sb_cnt_info));

#ifdef CONFIG_ECORE_SRIOV
max_vf_vlan_filters = ECORE_ETH_MAX_VF_NUM_VLAN_FILTERS;
#else
max_vf_vlan_filters = 0;
#endif

ecore_int_get_num_sbs(p_hwfn, &sb_cnt_info);
resc_num[ECORE_SB] = OSAL_MIN_T(u32,
Expand Down Expand Up @@ -2020,6 +2077,10 @@ ecore_get_hw_info(struct ecore_hwfn *p_hwfn,
{
enum _ecore_status_t rc;

rc = ecore_iov_hw_info(p_hwfn, p_hwfn->p_main_ptt);
if (rc)
return rc;

/* TODO In get_hw_info, amoungst others:
* Get MCP FW revision and determine according to it the supported
* featrues (e.g. DCB)
Expand Down Expand Up @@ -2177,6 +2238,9 @@ void ecore_prepare_hibernate(struct ecore_dev *p_dev)
{
int j;

if (IS_VF(p_dev))
return;

for_each_hwfn(p_dev, j) {
struct ecore_hwfn *p_hwfn = &p_dev->hwfns[j];

Expand Down Expand Up @@ -2276,6 +2340,9 @@ enum _ecore_status_t ecore_hw_prepare(struct ecore_dev *p_dev, int personality)
struct ecore_hwfn *p_hwfn = ECORE_LEADING_HWFN(p_dev);
enum _ecore_status_t rc;

if (IS_VF(p_dev))
return ecore_vf_hw_prepare(p_dev);

/* Store the precompiled init data ptrs */
ecore_init_iro_array(p_dev);

Expand Down Expand Up @@ -2327,6 +2394,11 @@ void ecore_hw_remove(struct ecore_dev *p_dev)
for_each_hwfn(p_dev, i) {
struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];

if (IS_VF(p_dev)) {
ecore_vf_pf_release(p_hwfn);
continue;
}

ecore_init_free(p_hwfn);
ecore_hw_hwfn_free(p_hwfn);
ecore_mcp_free(p_hwfn);
Expand Down Expand Up @@ -2954,6 +3026,11 @@ static enum _ecore_status_t ecore_set_coalesce(struct ecore_hwfn *p_hwfn,
{
struct coalescing_timeset *p_coalesce_timeset;

if (IS_VF(p_hwfn->p_dev)) {
DP_NOTICE(p_hwfn, true, "VF coalescing config not supported\n");
return ECORE_INVAL;
}

if (p_hwfn->p_dev->int_coalescing_mode != ECORE_COAL_MODE_ENABLE) {
DP_NOTICE(p_hwfn, true,
"Coalescing configuration not enabled\n");
Expand Down
9 changes: 7 additions & 2 deletions drivers/net/qede/base/ecore_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "ecore_hw.h"
#include "reg_addr.h"
#include "ecore_utils.h"
#include "ecore_iov_api.h"

#ifndef ASIC_ONLY
#define ECORE_EMUL_FACTOR 2000
Expand Down Expand Up @@ -243,8 +244,12 @@ static void ecore_memcpy_hw(struct ecore_hwfn *p_hwfn,
quota = OSAL_MIN_T(osal_size_t, n - done,
PXP_EXTERNAL_BAR_PF_WINDOW_SINGLE_SIZE);

ecore_ptt_set_win(p_hwfn, p_ptt, hw_addr + done);
hw_offset = ecore_ptt_get_bar_addr(p_ptt);
if (IS_PF(p_hwfn->p_dev)) {
ecore_ptt_set_win(p_hwfn, p_ptt, hw_addr + done);
hw_offset = ecore_ptt_get_bar_addr(p_ptt);
} else {
hw_offset = hw_addr + done;
}

dw_count = quota / 4;
host_addr = (u32 *)((u8 *)addr + done);
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/qede/base/ecore_init_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "ecore_init_fw_funcs.h"

#include "ecore_iro_values.h"
#include "ecore_sriov.h"
#include "ecore_gtt_values.h"
#include "reg_addr.h"
#include "ecore_init_ops.h"
Expand Down Expand Up @@ -102,6 +103,9 @@ enum _ecore_status_t ecore_init_alloc(struct ecore_hwfn *p_hwfn)
{
struct ecore_rt_data *rt_data = &p_hwfn->rt_data;

if (IS_VF(p_hwfn->p_dev))
return ECORE_SUCCESS;

rt_data->b_valid = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
sizeof(bool) * RUNTIME_ARRAY_SIZE);
if (!rt_data->b_valid)
Expand Down
Loading

0 comments on commit 86a2265

Please sign in to comment.