Commit 769c500d authored by Akeem G Abodunrin's avatar Akeem G Abodunrin Committed by Tony Nguyen

ice: Add advanced power mgmt for WoL

Add callbacks needed to support advanced power management for Wake on LAN.
Also make ice_pf_state_is_nominal function available for all configurations
not just CONFIG_PCI_IOV.
Signed-off-by: default avatarAkeem G Abodunrin <akeem.g.abodunrin@intel.com>
Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 81aed647
...@@ -423,6 +423,8 @@ struct ice_pf { ...@@ -423,6 +423,8 @@ struct ice_pf {
u16 empr_count; /* EMP reset count */ u16 empr_count; /* EMP reset count */
u16 pfr_count; /* PF reset count */ u16 pfr_count; /* PF reset count */
u8 wol_ena : 1; /* software state of WoL */
u32 wakeup_reason; /* last wakeup reason */
struct ice_hw_port_stats stats; struct ice_hw_port_stats stats;
struct ice_hw_port_stats stats_prev; struct ice_hw_port_stats stats_prev;
struct ice_hw hw; struct ice_hw hw;
...@@ -568,6 +570,7 @@ int ice_schedule_reset(struct ice_pf *pf, enum ice_reset_req reset); ...@@ -568,6 +570,7 @@ int ice_schedule_reset(struct ice_pf *pf, enum ice_reset_req reset);
void ice_print_link_msg(struct ice_vsi *vsi, bool isup); void ice_print_link_msg(struct ice_vsi *vsi, bool isup);
const char *ice_stat_str(enum ice_status stat_err); const char *ice_stat_str(enum ice_status stat_err);
const char *ice_aq_str(enum ice_aq_err aq_err); const char *ice_aq_str(enum ice_aq_err aq_err);
bool ice_is_wol_supported(struct ice_pf *pf);
int int
ice_fdir_write_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input, bool add, ice_fdir_write_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input, bool add,
bool is_tun); bool is_tun);
......
...@@ -3322,6 +3322,58 @@ static int ice_set_channels(struct net_device *dev, struct ethtool_channels *ch) ...@@ -3322,6 +3322,58 @@ static int ice_set_channels(struct net_device *dev, struct ethtool_channels *ch)
return 0; return 0;
} }
/**
* ice_get_wol - get current Wake on LAN configuration
* @netdev: network interface device structure
* @wol: Ethtool structure to retrieve WoL settings
*/
static void ice_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct ice_netdev_priv *np = netdev_priv(netdev);
struct ice_pf *pf = np->vsi->back;
if (np->vsi->type != ICE_VSI_PF)
netdev_warn(netdev, "Wake on LAN is not supported on this interface!\n");
/* Get WoL settings based on the HW capability */
if (ice_is_wol_supported(pf)) {
wol->supported = WAKE_MAGIC;
wol->wolopts = pf->wol_ena ? WAKE_MAGIC : 0;
} else {
wol->supported = 0;
wol->wolopts = 0;
}
}
/**
* ice_set_wol - set Wake on LAN on supported device
* @netdev: network interface device structure
* @wol: Ethtool structure to set WoL
*/
static int ice_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct ice_netdev_priv *np = netdev_priv(netdev);
struct ice_vsi *vsi = np->vsi;
struct ice_pf *pf = vsi->back;
if (vsi->type != ICE_VSI_PF || !ice_is_wol_supported(pf))
return -EOPNOTSUPP;
/* only magic packet is supported */
if (wol->wolopts && wol->wolopts != WAKE_MAGIC)
return -EOPNOTSUPP;
/* Set WoL only if there is a new value */
if (pf->wol_ena != !!wol->wolopts) {
pf->wol_ena = !!wol->wolopts;
device_set_wakeup_enable(ice_pf_to_dev(pf), pf->wol_ena);
netdev_dbg(netdev, "WoL magic packet %sabled\n",
pf->wol_ena ? "en" : "dis");
}
return 0;
}
enum ice_container_type { enum ice_container_type {
ICE_RX_CONTAINER, ICE_RX_CONTAINER,
ICE_TX_CONTAINER, ICE_TX_CONTAINER,
...@@ -3805,6 +3857,8 @@ static const struct ethtool_ops ice_ethtool_ops = { ...@@ -3805,6 +3857,8 @@ static const struct ethtool_ops ice_ethtool_ops = {
.get_drvinfo = ice_get_drvinfo, .get_drvinfo = ice_get_drvinfo,
.get_regs_len = ice_get_regs_len, .get_regs_len = ice_get_regs_len,
.get_regs = ice_get_regs, .get_regs = ice_get_regs,
.get_wol = ice_get_wol,
.set_wol = ice_set_wol,
.get_msglevel = ice_get_msglevel, .get_msglevel = ice_get_msglevel,
.set_msglevel = ice_set_msglevel, .set_msglevel = ice_set_msglevel,
.self_test = ice_self_test, .self_test = ice_self_test,
...@@ -3847,6 +3901,8 @@ static const struct ethtool_ops ice_ethtool_safe_mode_ops = { ...@@ -3847,6 +3901,8 @@ static const struct ethtool_ops ice_ethtool_safe_mode_ops = {
.get_drvinfo = ice_get_drvinfo, .get_drvinfo = ice_get_drvinfo,
.get_regs_len = ice_get_regs_len, .get_regs_len = ice_get_regs_len,
.get_regs = ice_get_regs, .get_regs = ice_get_regs,
.get_wol = ice_get_wol,
.set_wol = ice_set_wol,
.get_msglevel = ice_get_msglevel, .get_msglevel = ice_get_msglevel,
.set_msglevel = ice_set_msglevel, .set_msglevel = ice_set_msglevel,
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
......
...@@ -367,6 +367,15 @@ ...@@ -367,6 +367,15 @@
#define VSIQF_FD_CNT_FD_GCNT_M ICE_M(0x3FFF, 0) #define VSIQF_FD_CNT_FD_GCNT_M ICE_M(0x3FFF, 0)
#define VSIQF_HKEY_MAX_INDEX 12 #define VSIQF_HKEY_MAX_INDEX 12
#define VSIQF_HLUT_MAX_INDEX 15 #define VSIQF_HLUT_MAX_INDEX 15
#define PFPM_APM 0x000B8080
#define PFPM_APM_APME_M BIT(0)
#define PFPM_WUFC 0x0009DC00
#define PFPM_WUFC_MAG_M BIT(1)
#define PFPM_WUS 0x0009DB80
#define PFPM_WUS_LNKC_M BIT(0)
#define PFPM_WUS_MAG_M BIT(1)
#define PFPM_WUS_MNG_M BIT(3)
#define PFPM_WUS_FW_RST_WK_M BIT(31)
#define VFINT_DYN_CTLN(_i) (0x00003800 + ((_i) * 4)) #define VFINT_DYN_CTLN(_i) (0x00003800 + ((_i) * 4))
#define VFINT_DYN_CTLN_CLEARPBA_M BIT(1) #define VFINT_DYN_CTLN_CLEARPBA_M BIT(1)
#define PRTRPB_RDPC 0x000AC260 #define PRTRPB_RDPC 0x000AC260
......
...@@ -1467,6 +1467,30 @@ static void ice_vsi_set_rss_flow_fld(struct ice_vsi *vsi) ...@@ -1467,6 +1467,30 @@ static void ice_vsi_set_rss_flow_fld(struct ice_vsi *vsi)
vsi_num, ice_stat_str(status)); vsi_num, ice_stat_str(status));
} }
/**
* ice_pf_state_is_nominal - checks the PF for nominal state
* @pf: pointer to PF to check
*
* Check the PF's state for a collection of bits that would indicate
* the PF is in a state that would inhibit normal operation for
* driver functionality.
*
* Returns true if PF is in a nominal state, false otherwise
*/
bool ice_pf_state_is_nominal(struct ice_pf *pf)
{
DECLARE_BITMAP(check_bits, __ICE_STATE_NBITS) = { 0 };
if (!pf)
return false;
bitmap_set(check_bits, 0, __ICE_STATE_NOMINAL_CHECK_BITS);
if (bitmap_intersects(pf->state, check_bits, __ICE_STATE_NBITS))
return false;
return true;
}
/** /**
* ice_update_eth_stats - Update VSI-specific ethernet statistics counters * ice_update_eth_stats - Update VSI-specific ethernet statistics counters
* @vsi: the VSI to be updated * @vsi: the VSI to be updated
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
const char *ice_vsi_type_str(enum ice_vsi_type vsi_type); const char *ice_vsi_type_str(enum ice_vsi_type vsi_type);
bool ice_pf_state_is_nominal(struct ice_pf *pf);
void ice_update_eth_stats(struct ice_vsi *vsi); void ice_update_eth_stats(struct ice_vsi *vsi);
int ice_vsi_cfg_rxqs(struct ice_vsi *vsi); int ice_vsi_cfg_rxqs(struct ice_vsi *vsi);
......
This diff is collapsed.
...@@ -172,8 +172,7 @@ void ice_release_nvm(struct ice_hw *hw) ...@@ -172,8 +172,7 @@ void ice_release_nvm(struct ice_hw *hw)
* *
* Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq. * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
*/ */
static enum ice_status enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
{ {
enum ice_status status; enum ice_status status;
......
...@@ -13,4 +13,5 @@ ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data, ...@@ -13,4 +13,5 @@ ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
enum ice_status enum ice_status
ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size); ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size);
enum ice_status ice_init_nvm(struct ice_hw *hw); enum ice_status ice_init_nvm(struct ice_hw *hw);
enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data);
#endif /* _ICE_NVM_H_ */ #endif /* _ICE_NVM_H_ */
...@@ -709,6 +709,7 @@ struct ice_hw_port_stats { ...@@ -709,6 +709,7 @@ struct ice_hw_port_stats {
/* Checksum and Shadow RAM pointers */ /* Checksum and Shadow RAM pointers */
#define ICE_SR_BOOT_CFG_PTR 0x132 #define ICE_SR_BOOT_CFG_PTR 0x132
#define ICE_SR_NVM_WOL_CFG 0x19
#define ICE_NVM_OROM_VER_OFF 0x02 #define ICE_NVM_OROM_VER_OFF 0x02
#define ICE_SR_PBA_BLOCK_PTR 0x16 #define ICE_SR_PBA_BLOCK_PTR 0x16
#define ICE_SR_NVM_DEV_STARTER_VER 0x18 #define ICE_SR_NVM_DEV_STARTER_VER 0x18
......
...@@ -1592,31 +1592,6 @@ static int ice_ena_vfs(struct ice_pf *pf, u16 num_vfs) ...@@ -1592,31 +1592,6 @@ static int ice_ena_vfs(struct ice_pf *pf, u16 num_vfs)
return ret; return ret;
} }
/**
* ice_pf_state_is_nominal - checks the PF for nominal state
* @pf: pointer to PF to check
*
* Check the PF's state for a collection of bits that would indicate
* the PF is in a state that would inhibit normal operation for
* driver functionality.
*
* Returns true if PF is in a nominal state.
* Returns false otherwise
*/
static bool ice_pf_state_is_nominal(struct ice_pf *pf)
{
DECLARE_BITMAP(check_bits, __ICE_STATE_NBITS) = { 0 };
if (!pf)
return false;
bitmap_set(check_bits, 0, __ICE_STATE_NOMINAL_CHECK_BITS);
if (bitmap_intersects(pf->state, check_bits, __ICE_STATE_NBITS))
return false;
return true;
}
/** /**
* ice_pci_sriov_ena - Enable or change number of VFs * ice_pci_sriov_ena - Enable or change number of VFs
* @pf: pointer to the PF structure * @pf: pointer to the PF structure
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment