Skip to content

Commit

Permalink
ice: Initialize RDMA support
Browse files Browse the repository at this point in the history
Probe the device's capabilities to see if it supports RDMA. If so, allocate
and reserve resources to support its operation; populate structures with
initial values.

Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Dave Ertman authored and Tony Nguyen committed May 29, 2021
1 parent e860fa9 commit d25a0fc
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 9 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ice/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ice-y := ice_main.o \
ice_ethtool_fdir.o \
ice_flex_pipe.o \
ice_flow.o \
ice_idc.o \
ice_devlink.o \
ice_fw_update.o \
ice_lag.o \
Expand Down
30 changes: 29 additions & 1 deletion drivers/net/ethernet/intel/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
#define ICE_MIN_LAN_OICR_MSIX 1
#define ICE_MIN_MSIX (ICE_MIN_LAN_TXRX_MSIX + ICE_MIN_LAN_OICR_MSIX)
#define ICE_FDIR_MSIX 2
#define ICE_RDMA_NUM_AEQ_MSIX 4
#define ICE_MIN_RDMA_MSIX 2
#define ICE_NO_VSI 0xffff
#define ICE_VSI_MAP_CONTIG 0
#define ICE_VSI_MAP_SCATTER 1
Expand All @@ -88,8 +90,9 @@
#define ICE_MAX_LG_RSS_QS 256
#define ICE_RES_VALID_BIT 0x8000
#define ICE_RES_MISC_VEC_ID (ICE_RES_VALID_BIT - 1)
#define ICE_RES_RDMA_VEC_ID (ICE_RES_MISC_VEC_ID - 1)
/* All VF control VSIs share the same IRQ, so assign a unique ID for them */
#define ICE_RES_VF_CTRL_VEC_ID (ICE_RES_MISC_VEC_ID - 1)
#define ICE_RES_VF_CTRL_VEC_ID (ICE_RES_RDMA_VEC_ID - 1)
#define ICE_INVAL_Q_INDEX 0xffff
#define ICE_INVAL_VFID 256

Expand Down Expand Up @@ -373,12 +376,14 @@ struct ice_q_vector {

enum ice_pf_flags {
ICE_FLAG_FLTR_SYNC,
ICE_FLAG_RDMA_ENA,
ICE_FLAG_RSS_ENA,
ICE_FLAG_SRIOV_ENA,
ICE_FLAG_SRIOV_CAPABLE,
ICE_FLAG_DCB_CAPABLE,
ICE_FLAG_DCB_ENA,
ICE_FLAG_FD_ENA,
ICE_FLAG_AUX_ENA,
ICE_FLAG_ADV_FEATURES,
ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA,
ICE_FLAG_TOTAL_PORT_SHUTDOWN_ENA,
Expand Down Expand Up @@ -439,6 +444,8 @@ struct ice_pf {
struct mutex sw_mutex; /* lock for protecting VSI alloc flow */
struct mutex tc_mutex; /* lock to protect TC changes */
u32 msg_enable;
u16 num_rdma_msix; /* Total MSIX vectors for RDMA driver */
u16 rdma_base_vector;

/* spinlock to protect the AdminQ wait list */
spinlock_t aq_wait_lock;
Expand Down Expand Up @@ -471,6 +478,8 @@ struct ice_pf {
unsigned long tx_timeout_last_recovery;
u32 tx_timeout_recovery_level;
char int_name[ICE_INT_NAME_STR_LEN];
struct auxiliary_device *adev;
int aux_idx;
u32 sw_int_count;

__le64 nvm_phy_type_lo; /* NVM PHY type low */
Expand Down Expand Up @@ -636,6 +645,7 @@ int ice_get_rss_key(struct ice_vsi *vsi, u8 *seed);
void ice_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size);
int ice_schedule_reset(struct ice_pf *pf, enum ice_reset_req reset);
void ice_print_link_msg(struct ice_vsi *vsi, bool isup);
int ice_init_rdma(struct ice_pf *pf);
const char *ice_stat_str(enum ice_status stat_err);
const char *ice_aq_str(enum ice_aq_err aq_err);
bool ice_is_wol_supported(struct ice_hw *hw);
Expand All @@ -660,4 +670,22 @@ int ice_open_internal(struct net_device *netdev);
int ice_stop(struct net_device *netdev);
void ice_service_task_schedule(struct ice_pf *pf);

/**
* ice_set_rdma_cap - enable RDMA support
* @pf: PF struct
*/
static inline void ice_set_rdma_cap(struct ice_pf *pf)
{
if (pf->hw.func_caps.common_cap.rdma && pf->num_rdma_msix)
set_bit(ICE_FLAG_RDMA_ENA, pf->flags);
}

/**
* ice_clear_rdma_cap - disable RDMA support
* @pf: PF struct
*/
static inline void ice_clear_rdma_cap(struct ice_pf *pf)
{
clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);
}
#endif /* _ICE_H_ */
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ struct ice_aqc_list_caps_elem {
#define ICE_AQC_CAPS_PENDING_OROM_VER 0x004B
#define ICE_AQC_CAPS_NET_VER 0x004C
#define ICE_AQC_CAPS_PENDING_NET_VER 0x004D
#define ICE_AQC_CAPS_RDMA 0x0051
#define ICE_AQC_CAPS_NVM_MGMT 0x0080

u8 major_ver;
Expand Down
17 changes: 16 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,8 @@ enum ice_status ice_check_reset(struct ice_hw *hw)
GLNVM_ULD_POR_DONE_1_M |\
GLNVM_ULD_PCIER_DONE_2_M)

uld_mask = ICE_RESET_DONE_MASK;
uld_mask = ICE_RESET_DONE_MASK | (hw->func_caps.common_cap.rdma ?
GLNVM_ULD_PE_DONE_M : 0);

/* Device is Active; check Global Reset processes are done */
for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) {
Expand Down Expand Up @@ -1938,6 +1939,10 @@ ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
ice_debug(hw, ICE_DBG_INIT, "%s: nvm_unified_update = %d\n", prefix,
caps->nvm_unified_update);
break;
case ICE_AQC_CAPS_RDMA:
caps->rdma = (number == 1);
ice_debug(hw, ICE_DBG_INIT, "%s: rdma = %d\n", prefix, caps->rdma);
break;
case ICE_AQC_CAPS_MAX_MTU:
caps->max_mtu = number;
ice_debug(hw, ICE_DBG_INIT, "%s: max_mtu = %d\n",
Expand Down Expand Up @@ -1971,6 +1976,16 @@ ice_recalc_port_limited_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps)
caps->maxtc = 4;
ice_debug(hw, ICE_DBG_INIT, "reducing maxtc to %d (based on #ports)\n",
caps->maxtc);
if (caps->rdma) {
ice_debug(hw, ICE_DBG_INIT, "forcing RDMA off\n");
caps->rdma = 0;
}

/* print message only when processing device capabilities
* during initialization.
*/
if (caps == &hw->dev_caps.common_cap)
dev_info(ice_hw_to_dev(hw), "RDMA functionality is not available with the current device configuration.\n");
}
}

Expand Down
43 changes: 43 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_idc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2021, Intel Corporation. */

/* Inter-Driver Communication */
#include "ice.h"
#include "ice_lib.h"
#include "ice_dcb_lib.h"

/**
* ice_reserve_rdma_qvector - Reserve vector resources for RDMA driver
* @pf: board private structure to initialize
*/
static int ice_reserve_rdma_qvector(struct ice_pf *pf)
{
if (test_bit(ICE_FLAG_RDMA_ENA, pf->flags)) {
int index;

index = ice_get_res(pf, pf->irq_tracker, pf->num_rdma_msix,
ICE_RES_RDMA_VEC_ID);
if (index < 0)
return index;
pf->num_avail_sw_msix -= pf->num_rdma_msix;
pf->rdma_base_vector = (u16)index;
}
return 0;
}

/**
* ice_init_rdma - initializes PF for RDMA use
* @pf: ptr to ice_pf
*/
int ice_init_rdma(struct ice_pf *pf)
{
struct device *dev = &pf->pdev->dev;
int ret;

/* Reserve vector resources */
ret = ice_reserve_rdma_qvector(pf);
if (ret < 0)
dev_err(dev, "failed to reserve vectors for RDMA\n");

return ret;
}
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_lag.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ ice_lag_link(struct ice_lag *lag, struct netdev_notifier_changeupper_info *info)
}

ice_clear_sriov_cap(pf);
ice_clear_rdma_cap(pf);

lag->bonded = true;
lag->role = ICE_LAG_UNSET;
Expand Down Expand Up @@ -222,6 +223,7 @@ ice_lag_unlink(struct ice_lag *lag,
}

ice_set_sriov_cap(pf);
ice_set_rdma_cap(pf);
lag->bonded = false;
lag->role = ICE_LAG_NONE;
}
Expand Down
11 changes: 11 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,17 @@ bool ice_is_safe_mode(struct ice_pf *pf)
return !test_bit(ICE_FLAG_ADV_FEATURES, pf->flags);
}

/**
* ice_is_aux_ena
* @pf: pointer to the PF struct
*
* returns true if AUX devices/drivers are supported, false otherwise
*/
bool ice_is_aux_ena(struct ice_pf *pf)
{
return test_bit(ICE_FLAG_AUX_ENA, pf->flags);
}

/**
* ice_vsi_clean_rss_flow_fld - Delete RSS configuration
* @vsi: the VSI being cleaned up
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/ice/ice_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ enum ice_status
ice_vsi_cfg_mac_fltr(struct ice_vsi *vsi, const u8 *macaddr, bool set);

bool ice_is_safe_mode(struct ice_pf *pf);

bool ice_is_aux_ena(struct ice_pf *pf);
bool ice_is_dflt_vsi_in_use(struct ice_sw *sw);

bool ice_is_vsi_dflt_vsi(struct ice_sw *sw, struct ice_vsi *vsi);
Expand Down
84 changes: 78 additions & 6 deletions drivers/net/ethernet/intel/ice/ice_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ MODULE_PARM_DESC(debug, "netif level (0=none,...,16=all), hw debug_mask (0x8XXXX
MODULE_PARM_DESC(debug, "netif level (0=none,...,16=all)");
#endif /* !CONFIG_DYNAMIC_DEBUG */

static DEFINE_IDA(ice_aux_ida);

static struct workqueue_struct *ice_wq;
static const struct net_device_ops ice_netdev_safe_mode_ops;
static const struct net_device_ops ice_netdev_ops;
Expand Down Expand Up @@ -3276,6 +3278,12 @@ static void ice_set_pf_caps(struct ice_pf *pf)
{
struct ice_hw_func_caps *func_caps = &pf->hw.func_caps;

clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);
clear_bit(ICE_FLAG_AUX_ENA, pf->flags);
if (func_caps->common_cap.rdma) {
set_bit(ICE_FLAG_RDMA_ENA, pf->flags);
set_bit(ICE_FLAG_AUX_ENA, pf->flags);
}
clear_bit(ICE_FLAG_DCB_CAPABLE, pf->flags);
if (func_caps->common_cap.dcb)
set_bit(ICE_FLAG_DCB_CAPABLE, pf->flags);
Expand Down Expand Up @@ -3355,11 +3363,12 @@ static int ice_init_pf(struct ice_pf *pf)
*/
static int ice_ena_msix_range(struct ice_pf *pf)
{
int v_left, v_actual, v_other, v_budget = 0;
int num_cpus, v_left, v_actual, v_other, v_budget = 0;
struct device *dev = ice_pf_to_dev(pf);
int needed, err, i;

v_left = pf->hw.func_caps.common_cap.num_msix_vectors;
num_cpus = num_online_cpus();

/* reserve for LAN miscellaneous handler */
needed = ICE_MIN_LAN_OICR_MSIX;
Expand All @@ -3381,13 +3390,23 @@ static int ice_ena_msix_range(struct ice_pf *pf)
v_other = v_budget;

/* reserve vectors for LAN traffic */
needed = min_t(int, num_online_cpus(), v_left);
needed = num_cpus;
if (v_left < needed)
goto no_hw_vecs_left_err;
pf->num_lan_msix = needed;
v_budget += needed;
v_left -= needed;

/* reserve vectors for RDMA auxiliary driver */
if (test_bit(ICE_FLAG_RDMA_ENA, pf->flags)) {
needed = num_cpus + ICE_RDMA_NUM_AEQ_MSIX;
if (v_left < needed)
goto no_hw_vecs_left_err;
pf->num_rdma_msix = needed;
v_budget += needed;
v_left -= needed;
}

pf->msix_entries = devm_kcalloc(dev, v_budget,
sizeof(*pf->msix_entries), GFP_KERNEL);
if (!pf->msix_entries) {
Expand Down Expand Up @@ -3417,16 +3436,46 @@ static int ice_ena_msix_range(struct ice_pf *pf)
err = -ERANGE;
goto msix_err;
} else {
int v_traffic = v_actual - v_other;
int v_remain = v_actual - v_other;
int v_rdma = 0, v_min_rdma = 0;

if (test_bit(ICE_FLAG_RDMA_ENA, pf->flags)) {
/* Need at least 1 interrupt in addition to
* AEQ MSIX
*/
v_rdma = ICE_RDMA_NUM_AEQ_MSIX + 1;
v_min_rdma = ICE_MIN_RDMA_MSIX;
}

if (v_actual == ICE_MIN_MSIX ||
v_traffic < ICE_MIN_LAN_TXRX_MSIX)
v_remain < ICE_MIN_LAN_TXRX_MSIX + v_min_rdma) {
dev_warn(dev, "Not enough MSI-X vectors to support RDMA.\n");
clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);

pf->num_rdma_msix = 0;
pf->num_lan_msix = ICE_MIN_LAN_TXRX_MSIX;
else
pf->num_lan_msix = v_traffic;
} else if ((v_remain < ICE_MIN_LAN_TXRX_MSIX + v_rdma) ||
(v_remain - v_rdma < v_rdma)) {
/* Support minimum RDMA and give remaining
* vectors to LAN MSIX
*/
pf->num_rdma_msix = v_min_rdma;
pf->num_lan_msix = v_remain - v_min_rdma;
} else {
/* Split remaining MSIX with RDMA after
* accounting for AEQ MSIX
*/
pf->num_rdma_msix = (v_remain - ICE_RDMA_NUM_AEQ_MSIX) / 2 +
ICE_RDMA_NUM_AEQ_MSIX;
pf->num_lan_msix = v_remain - pf->num_rdma_msix;
}

dev_notice(dev, "Enabled %d MSI-X vectors for LAN traffic.\n",
pf->num_lan_msix);

if (test_bit(ICE_FLAG_RDMA_ENA, pf->flags))
dev_notice(dev, "Enabled %d MSI-X vectors for RDMA.\n",
pf->num_rdma_msix);
}
}

Expand All @@ -3441,6 +3490,7 @@ static int ice_ena_msix_range(struct ice_pf *pf)
needed, v_left);
err = -ERANGE;
exit_err:
pf->num_rdma_msix = 0;
pf->num_lan_msix = 0;
return err;
}
Expand Down Expand Up @@ -4268,8 +4318,29 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)

/* ready to go, so clear down state bit */
clear_bit(ICE_DOWN, pf->state);
if (ice_is_aux_ena(pf)) {
pf->aux_idx = ida_alloc(&ice_aux_ida, GFP_KERNEL);
if (pf->aux_idx < 0) {
dev_err(dev, "Failed to allocate device ID for AUX driver\n");
err = -ENOMEM;
goto err_netdev_reg;
}

err = ice_init_rdma(pf);
if (err) {
dev_err(dev, "Failed to initialize RDMA: %d\n", err);
err = -EIO;
goto err_init_aux_unroll;
}
} else {
dev_warn(dev, "RDMA is not supported on this device\n");
}

return 0;

err_init_aux_unroll:
pf->adev = NULL;
ida_free(&ice_aux_ida, pf->aux_idx);
err_netdev_reg:
err_send_version_unroll:
ice_vsi_release_all(pf);
Expand Down Expand Up @@ -4383,6 +4454,7 @@ static void ice_remove(struct pci_dev *pdev)
ice_service_task_stop(pf);

ice_aq_cancel_waiting_tasks(pf);
ida_free(&ice_aux_ida, pf->aux_idx);

mutex_destroy(&(&pf->hw)->fdir_fltr_lock);
ice_deinit_lag(pf);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ice/ice_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ struct ice_hw_common_caps {
u8 rss_table_entry_width; /* RSS Entry width in bits */

u8 dcb;
u8 rdma;

bool nvm_update_pending_nvm;
bool nvm_update_pending_orom;
Expand Down

0 comments on commit d25a0fc

Please sign in to comment.