Skip to content

Commit

Permalink
ice: Enable DDP package download
Browse files Browse the repository at this point in the history
Attempt to request an optional device-specific DDP package file
(one with the PCIe Device Serial Number in its name so that different DDP
package files can be used on different devices). If the optional package
file exists, download it to the device. If not, download the default
package file.

Log an appropriate message based on whether or not a DDP package
file exists and the return code from the attempt to download it to the
device.  If the download fails and there is not already a package file on
the device, go into "Safe Mode" where some features are not supported.

Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Tony Nguyen authored and Jeff Kirsher committed Sep 12, 2019
1 parent 32d63fa commit 462acf6
Show file tree
Hide file tree
Showing 12 changed files with 679 additions and 195 deletions.
14 changes: 14 additions & 0 deletions drivers/net/ethernet/intel/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/netdevice.h>
#include <linux/compiler.h>
#include <linux/etherdevice.h>
Expand Down Expand Up @@ -307,6 +308,7 @@ enum ice_pf_flags {
ICE_FLAG_SRIOV_CAPABLE,
ICE_FLAG_DCB_CAPABLE,
ICE_FLAG_DCB_ENA,
ICE_FLAG_ADV_FEATURES,
ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA,
ICE_FLAG_NO_MEDIA,
ICE_FLAG_FW_LLDP_AGENT,
Expand Down Expand Up @@ -404,6 +406,17 @@ ice_irq_dynamic_ena(struct ice_hw *hw, struct ice_vsi *vsi,
wr32(hw, GLINT_DYN_CTL(vector), val);
}

/**
* ice_netdev_to_pf - Retrieve the PF struct associated with a netdev
* @netdev: pointer to the netdev struct
*/
static inline struct ice_pf *ice_netdev_to_pf(struct net_device *netdev)
{
struct ice_netdev_priv *np = netdev_priv(netdev);

return np->vsi->back;
}

/**
* ice_get_main_vsi - Get the PF VSI
* @pf: PF instance
Expand All @@ -421,6 +434,7 @@ static inline struct ice_vsi *ice_get_main_vsi(struct ice_pf *pf)
int ice_vsi_setup_tx_rings(struct ice_vsi *vsi);
int ice_vsi_setup_rx_rings(struct ice_vsi *vsi);
void ice_set_ethtool_ops(struct net_device *netdev);
void ice_set_ethtool_safe_mode_ops(struct net_device *netdev);
u16 ice_get_avail_txq_count(struct ice_pf *pf);
u16 ice_get_avail_rxq_count(struct ice_pf *pf);
void ice_update_vsi_stats(struct ice_vsi *vsi);
Expand Down
69 changes: 69 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1846,6 +1846,75 @@ ice_discover_caps(struct ice_hw *hw, enum ice_adminq_opc opc)
return status;
}

/**
* ice_set_safe_mode_caps - Override dev/func capabilities when in safe mode
* @hw: pointer to the hardware structure
*/
void ice_set_safe_mode_caps(struct ice_hw *hw)
{
struct ice_hw_func_caps *func_caps = &hw->func_caps;
struct ice_hw_dev_caps *dev_caps = &hw->dev_caps;
u32 valid_func, rxq_first_id, txq_first_id;
u32 msix_vector_first_id, max_mtu;
u32 num_func = 0;
u8 i;

/* cache some func_caps values that should be restored after memset */
valid_func = func_caps->common_cap.valid_functions;
txq_first_id = func_caps->common_cap.txq_first_id;
rxq_first_id = func_caps->common_cap.rxq_first_id;
msix_vector_first_id = func_caps->common_cap.msix_vector_first_id;
max_mtu = func_caps->common_cap.max_mtu;

/* unset func capabilities */
memset(func_caps, 0, sizeof(*func_caps));

/* restore cached values */
func_caps->common_cap.valid_functions = valid_func;
func_caps->common_cap.txq_first_id = txq_first_id;
func_caps->common_cap.rxq_first_id = rxq_first_id;
func_caps->common_cap.msix_vector_first_id = msix_vector_first_id;
func_caps->common_cap.max_mtu = max_mtu;

/* one Tx and one Rx queue in safe mode */
func_caps->common_cap.num_rxq = 1;
func_caps->common_cap.num_txq = 1;

/* two MSIX vectors, one for traffic and one for misc causes */
func_caps->common_cap.num_msix_vectors = 2;
func_caps->guar_num_vsi = 1;

/* cache some dev_caps values that should be restored after memset */
valid_func = dev_caps->common_cap.valid_functions;
txq_first_id = dev_caps->common_cap.txq_first_id;
rxq_first_id = dev_caps->common_cap.rxq_first_id;
msix_vector_first_id = dev_caps->common_cap.msix_vector_first_id;
max_mtu = dev_caps->common_cap.max_mtu;

/* unset dev capabilities */
memset(dev_caps, 0, sizeof(*dev_caps));

/* restore cached values */
dev_caps->common_cap.valid_functions = valid_func;
dev_caps->common_cap.txq_first_id = txq_first_id;
dev_caps->common_cap.rxq_first_id = rxq_first_id;
dev_caps->common_cap.msix_vector_first_id = msix_vector_first_id;
dev_caps->common_cap.max_mtu = max_mtu;

/* valid_func is a bitmap. get number of functions */
#define ICE_MAX_FUNCS 8
for (i = 0; i < ICE_MAX_FUNCS; i++)
if (valid_func & BIT(i))
num_func++;

/* one Tx and one Rx queue per function in safe mode */
dev_caps->common_cap.num_rxq = num_func;
dev_caps->common_cap.num_txq = num_func;

/* two MSIX vectors per function */
dev_caps->common_cap.num_msix_vectors = 2 * num_func;
}

/**
* ice_get_caps - get info about the HW
* @hw: pointer to the hardware structure
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq,
void ice_clear_pxe_mode(struct ice_hw *hw);
enum ice_status ice_get_caps(struct ice_hw *hw);

void ice_set_safe_mode_caps(struct ice_hw *hw);

void ice_dev_onetime_setup(struct ice_hw *hw);

enum ice_status
Expand Down
42 changes: 42 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_dcb_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,48 @@

#include "ice_dcb_lib.h"

/**
* ice_vsi_cfg_netdev_tc - Setup the netdev TC configuration
* @vsi: the VSI being configured
* @ena_tc: TC map to be enabled
*/
void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc)
{
struct net_device *netdev = vsi->netdev;
struct ice_pf *pf = vsi->back;
struct ice_dcbx_cfg *dcbcfg;
u8 netdev_tc;
int i;

if (!netdev)
return;

if (!ena_tc) {
netdev_reset_tc(netdev);
return;
}

if (netdev_set_num_tc(netdev, vsi->tc_cfg.numtc))
return;

dcbcfg = &pf->hw.port_info->local_dcbx_cfg;

ice_for_each_traffic_class(i)
if (vsi->tc_cfg.ena_tc & BIT(i))
netdev_set_tc_queue(netdev,
vsi->tc_cfg.tc_info[i].netdev_tc,
vsi->tc_cfg.tc_info[i].qcount_tx,
vsi->tc_cfg.tc_info[i].qoffset);

for (i = 0; i < ICE_MAX_USER_PRIORITY; i++) {
u8 ets_tc = dcbcfg->etscfg.prio_table[i];

/* Get the mapped netdev TC# for the UP */
netdev_tc = vsi->tc_cfg.tc_info[ets_tc].netdev_tc;
netdev_set_prio_tc_map(netdev, i, netdev_tc);
}
}

/**
* ice_dcb_get_ena_tc - return bitmap of enabled TCs
* @dcbcfg: DCB config to evaluate for enabled TCs
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_dcb_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ice_tx_prepare_vlan_flags_dcb(struct ice_ring *tx_ring,
void
ice_dcb_process_lldp_set_mib_change(struct ice_pf *pf,
struct ice_rq_event_info *event);
void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc);
static inline void
ice_set_cgd_num(struct ice_tlan_ctx *tlan_ctx, struct ice_ring *ring)
{
Expand Down Expand Up @@ -58,5 +59,6 @@ ice_tx_prepare_vlan_flags_dcb(struct ice_ring __always_unused *tx_ring,
#define ice_vsi_cfg_dcb_rings(vsi) do {} while (0)
#define ice_dcb_process_lldp_set_mib_change(pf, event) do {} while (0)
#define ice_set_cgd_num(tlan_ctx, ring) do {} while (0)
#define ice_vsi_cfg_netdev_tc(vsi, ena_tc) do {} while (0)
#endif /* CONFIG_DCB */
#endif /* _ICE_DCB_LIB_H_ */
27 changes: 27 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -3435,6 +3435,33 @@ static const struct ethtool_ops ice_ethtool_ops = {
.set_fecparam = ice_set_fecparam,
};

static const struct ethtool_ops ice_ethtool_safe_mode_ops = {
.get_link_ksettings = ice_get_link_ksettings,
.set_link_ksettings = ice_set_link_ksettings,
.get_drvinfo = ice_get_drvinfo,
.get_regs_len = ice_get_regs_len,
.get_regs = ice_get_regs,
.get_msglevel = ice_get_msglevel,
.set_msglevel = ice_set_msglevel,
.get_eeprom_len = ice_get_eeprom_len,
.get_eeprom = ice_get_eeprom,
.get_strings = ice_get_strings,
.get_ethtool_stats = ice_get_ethtool_stats,
.get_sset_count = ice_get_sset_count,
.get_ringparam = ice_get_ringparam,
.set_ringparam = ice_set_ringparam,
.nway_reset = ice_nway_reset,
};

/**
* ice_set_ethtool_safe_mode_ops - setup safe mode ethtool ops
* @netdev: network interface device structure
*/
void ice_set_ethtool_safe_mode_ops(struct net_device *netdev)
{
netdev->ethtool_ops = &ice_ethtool_safe_mode_ops;
}

/**
* ice_set_ethtool_ops - setup netdev ethtool ops
* @netdev: network interface device structure
Expand Down
4 changes: 1 addition & 3 deletions drivers/net/ethernet/intel/ice/ice_flex_pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
#include "ice_common.h"
#include "ice_flex_pipe.h"

static void ice_fill_blk_tbls(struct ice_hw *hw);

/**
* ice_pkg_val_buf
* @buf: pointer to the ice buffer
Expand Down Expand Up @@ -1358,7 +1356,7 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)
* database with the data iteratively for all advanced feature
* blocks. Assume that the HW tables have been allocated.
*/
static void ice_fill_blk_tbls(struct ice_hw *hw)
void ice_fill_blk_tbls(struct ice_hw *hw)
{
u8 i;

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ice/ice_flex_pipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum ice_status
ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
enum ice_status ice_init_hw_tbls(struct ice_hw *hw);
void ice_free_seg(struct ice_hw *hw);
void ice_fill_blk_tbls(struct ice_hw *hw);
void ice_clear_hw_tbls(struct ice_hw *hw);
void ice_free_hw_tbls(struct ice_hw *hw);
#endif /* _ICE_FLEX_PIPE_H_ */
92 changes: 34 additions & 58 deletions drivers/net/ethernet/intel/ice/ice_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,17 @@ void ice_vsi_put_qs(struct ice_vsi *vsi)
mutex_unlock(&pf->avail_q_mutex);
}

/**
* ice_is_safe_mode
* @pf: pointer to the PF struct
*
* returns true if driver is in safe mode, false otherwise
*/
bool ice_is_safe_mode(struct ice_pf *pf)
{
return !test_bit(ICE_FLAG_ADV_FEATURES, pf->flags);
}

/**
* ice_rss_clean - Delete RSS related VSI structures that hold user inputs
* @vsi: the VSI being removed
Expand Down Expand Up @@ -2629,15 +2640,17 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
* DCB settings in the HW. Also, if the FW DCBX engine is not running
* then Rx LLDP packets need to be redirected up the stack.
*/
if (vsi->type == ICE_VSI_PF) {
ice_vsi_add_rem_eth_mac(vsi, true);
if (!ice_is_safe_mode(pf)) {
if (vsi->type == ICE_VSI_PF) {
ice_vsi_add_rem_eth_mac(vsi, true);

/* Tx LLDP packets */
ice_cfg_sw_lldp(vsi, true, true);
/* Tx LLDP packets */
ice_cfg_sw_lldp(vsi, true, true);

/* Rx LLDP packets */
if (!test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
ice_cfg_sw_lldp(vsi, false, true);
/* Rx LLDP packets */
if (!test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
ice_cfg_sw_lldp(vsi, false, true);
}
}

return vsi;
Expand Down Expand Up @@ -2905,8 +2918,11 @@ void ice_vsi_dis_irq(struct ice_vsi *vsi)
}

/* disable each interrupt */
ice_for_each_q_vector(vsi, i)
ice_for_each_q_vector(vsi, i) {
if (!vsi->q_vectors[i])
continue;
wr32(hw, GLINT_DYN_CTL(vsi->q_vectors[i]->reg_idx), 0);
}

ice_flush(hw);

Expand Down Expand Up @@ -2975,14 +2991,16 @@ int ice_vsi_release(struct ice_vsi *vsi)
pf->num_avail_sw_msix += vsi->num_q_vectors;
}

if (vsi->type == ICE_VSI_PF) {
ice_vsi_add_rem_eth_mac(vsi, false);
ice_cfg_sw_lldp(vsi, true, false);
/* The Rx rule will only exist to remove if the LLDP FW
* engine is currently stopped
*/
if (!test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
ice_cfg_sw_lldp(vsi, false, false);
if (!ice_is_safe_mode(pf)) {
if (vsi->type == ICE_VSI_PF) {
ice_vsi_add_rem_eth_mac(vsi, false);
ice_cfg_sw_lldp(vsi, true, false);
/* The Rx rule will only exist to remove if the LLDP FW
* engine is currently stopped
*/
if (!test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
ice_cfg_sw_lldp(vsi, false, false);
}
}

ice_remove_vsi_fltr(&pf->hw, vsi->idx);
Expand Down Expand Up @@ -3168,48 +3186,6 @@ static void ice_vsi_update_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctx)
sizeof(vsi->info.tc_mapping));
}

/**
* ice_vsi_cfg_netdev_tc - Setup the netdev TC configuration
* @vsi: the VSI being configured
* @ena_tc: TC map to be enabled
*/
static void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc)
{
struct net_device *netdev = vsi->netdev;
struct ice_pf *pf = vsi->back;
struct ice_dcbx_cfg *dcbcfg;
u8 netdev_tc;
int i;

if (!netdev)
return;

if (!ena_tc) {
netdev_reset_tc(netdev);
return;
}

if (netdev_set_num_tc(netdev, vsi->tc_cfg.numtc))
return;

dcbcfg = &pf->hw.port_info->local_dcbx_cfg;

ice_for_each_traffic_class(i)
if (vsi->tc_cfg.ena_tc & BIT(i))
netdev_set_tc_queue(netdev,
vsi->tc_cfg.tc_info[i].netdev_tc,
vsi->tc_cfg.tc_info[i].qcount_tx,
vsi->tc_cfg.tc_info[i].qoffset);

for (i = 0; i < ICE_MAX_USER_PRIORITY; i++) {
u8 ets_tc = dcbcfg->etscfg.prio_table[i];

/* Get the mapped netdev TC# for the UP */
netdev_tc = vsi->tc_cfg.tc_info[ets_tc].netdev_tc;
netdev_set_prio_tc_map(netdev, i, netdev_tc);
}
}

/**
* ice_vsi_cfg_tc - Configure VSI Tx Sched for given TC map
* @vsi: VSI to be configured
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ice/ice_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,5 @@ char *ice_nvm_version_str(struct ice_hw *hw);
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);
#endif /* !_ICE_LIB_H_ */
Loading

0 comments on commit 462acf6

Please sign in to comment.