Merge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2025-07-03

Vladimir Oltean converts Intel drivers (ice, igc, igb, ixgbe, i40e) to
utilize new timestamping API (ndo_hwtstamp_get() and ndo_hwtstamp_set()).

For ixgbe:
Paul, Don, Slawomir, and Radoslaw add Malicious Driver Detection (MDD)
support for X550 and E610 devices to detect, report, and handle
potentially malicious VFs.

Simon Horman corrects spelling mistakes.

For igbvf:
Kohei Enju removes a couple of unreported counters and adds reporting
of Tx timeouts.

* '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  igbvf: add tx_timeout_count to ethtool statistics
  igbvf: remove unused interrupt counter fields from struct igbvf_adapter
  ixgbe: spelling corrections
  ixgbe: turn off MDD while modifying SRRCTL
  ixgbe: add Tx hang detection unhandled MDD
  ixgbe: check for MDD events
  ixgbe: add MDD support
  i40e: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set()
  ixgbe: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set()
  igb: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set()
  igc: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set()
  ice: convert to ndo_hwtstamp_get() and ndo_hwtstamp_set()
====================

Link: https://patch.msgid.link/20250703174242.3829277-1-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-07-07 19:06:13 -07:00
commit 4b62261def
31 changed files with 595 additions and 235 deletions

View File

@ -661,7 +661,7 @@ struct i40e_pf {
struct ptp_clock_info ptp_caps;
struct sk_buff *ptp_tx_skb;
unsigned long ptp_tx_start;
struct hwtstamp_config tstamp_config;
struct kernel_hwtstamp_config tstamp_config;
struct timespec64 ptp_prev_hw_time;
struct work_struct ptp_extts0_work;
ktime_t ptp_reset_start;
@ -1303,8 +1303,11 @@ void i40e_ptp_tx_hang(struct i40e_pf *pf);
void i40e_ptp_tx_hwtstamp(struct i40e_pf *pf);
void i40e_ptp_rx_hwtstamp(struct i40e_pf *pf, struct sk_buff *skb, u8 index);
void i40e_ptp_set_increment(struct i40e_pf *pf);
int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr);
int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr);
int i40e_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config);
int i40e_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
void i40e_ptp_save_hw_time(struct i40e_pf *pf);
void i40e_ptp_restore_hw_time(struct i40e_pf *pf);
void i40e_ptp_init(struct i40e_pf *pf);

View File

@ -2954,27 +2954,6 @@ static int i40e_change_mtu(struct net_device *netdev, int new_mtu)
return 0;
}
/**
* i40e_ioctl - Access the hwtstamp interface
* @netdev: network interface device structure
* @ifr: interface request data
* @cmd: ioctl command
**/
int i40e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
switch (cmd) {
case SIOCGHWTSTAMP:
return i40e_ptp_get_ts_config(pf, ifr);
case SIOCSHWTSTAMP:
return i40e_ptp_set_ts_config(pf, ifr);
default:
return -EOPNOTSUPP;
}
}
/**
* i40e_vlan_stripping_enable - Turn on vlan stripping for the VSI
* @vsi: the vsi being adjusted
@ -13626,7 +13605,6 @@ static const struct net_device_ops i40e_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = i40e_set_mac,
.ndo_change_mtu = i40e_change_mtu,
.ndo_eth_ioctl = i40e_ioctl,
.ndo_tx_timeout = i40e_tx_timeout,
.ndo_vlan_rx_add_vid = i40e_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = i40e_vlan_rx_kill_vid,
@ -13654,6 +13632,8 @@ static const struct net_device_ops i40e_netdev_ops = {
.ndo_xsk_wakeup = i40e_xsk_wakeup,
.ndo_dfwd_add_station = i40e_fwd_add,
.ndo_dfwd_del_station = i40e_fwd_del,
.ndo_hwtstamp_get = i40e_ptp_hwtstamp_get,
.ndo_hwtstamp_set = i40e_ptp_hwtstamp_set,
};
/**

View File

@ -912,23 +912,26 @@ void i40e_ptp_set_increment(struct i40e_pf *pf)
}
/**
* i40e_ptp_get_ts_config - ioctl interface to read the HW timestamping
* @pf: Board private structure
* @ifr: ioctl data
* i40e_ptp_hwtstamp_get - interface to read the HW timestamping
* @netdev: Network device structure
* @config: Timestamping configuration structure
*
* Obtain the current hardware timestamping settigs as requested. To do this,
* keep a shadow copy of the timestamp settings rather than attempting to
* deconstruct it from the registers.
**/
int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
int i40e_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
struct hwtstamp_config *config = &pf->tstamp_config;
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags))
return -EOPNOTSUPP;
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
-EFAULT : 0;
*config = pf->tstamp_config;
return 0;
}
/**
@ -1167,7 +1170,7 @@ int i40e_ptp_alloc_pins(struct i40e_pf *pf)
* more broad if the specific filter is not directly supported.
**/
static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
struct hwtstamp_config *config)
struct kernel_hwtstamp_config *config)
{
struct i40e_hw *hw = &pf->hw;
u32 tsyntype, regval;
@ -1290,9 +1293,10 @@ static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
}
/**
* i40e_ptp_set_ts_config - ioctl interface to control the HW timestamping
* @pf: Board private structure
* @ifr: ioctl data
* i40e_ptp_hwtstamp_set - interface to control the HW timestamping
* @netdev: Network device structure
* @config: Timestamping configuration structure
* @extack: Netlink extended ack structure for error reporting
*
* Respond to the user filter requests and make the appropriate hardware
* changes here. The XL710 cannot support splitting of the Tx/Rx timestamping
@ -1303,26 +1307,25 @@ static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
* as the user receives the timestamps they care about and the user is notified
* the filter has been broadened.
**/
int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
int i40e_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct hwtstamp_config config;
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
int err;
if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags))
return -EOPNOTSUPP;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
err = i40e_ptp_set_timestamp_mode(pf, &config);
err = i40e_ptp_set_timestamp_mode(pf, config);
if (err)
return err;
/* save these settings for future reference */
pf->tstamp_config = config;
pf->tstamp_config = *config;
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
return 0;
}
/**

View File

@ -7901,27 +7901,6 @@ int ice_change_mtu(struct net_device *netdev, int new_mtu)
return err;
}
/**
* ice_eth_ioctl - Access the hwtstamp interface
* @netdev: network interface device structure
* @ifr: interface request data
* @cmd: ioctl command
*/
static int ice_eth_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
struct ice_netdev_priv *np = netdev_priv(netdev);
struct ice_pf *pf = np->vsi->back;
switch (cmd) {
case SIOCGHWTSTAMP:
return ice_ptp_get_ts_config(pf, ifr);
case SIOCSHWTSTAMP:
return ice_ptp_set_ts_config(pf, ifr);
default:
return -EOPNOTSUPP;
}
}
/**
* ice_aq_str - convert AQ err code to a string
* @aq_err: the AQ error code to convert
@ -9761,7 +9740,6 @@ static const struct net_device_ops ice_netdev_ops = {
.ndo_change_mtu = ice_change_mtu,
.ndo_get_stats64 = ice_get_stats64,
.ndo_set_tx_maxrate = ice_set_tx_maxrate,
.ndo_eth_ioctl = ice_eth_ioctl,
.ndo_set_vf_spoofchk = ice_set_vf_spoofchk,
.ndo_set_vf_mac = ice_set_vf_mac,
.ndo_get_vf_config = ice_get_vf_cfg,
@ -9785,4 +9763,6 @@ static const struct net_device_ops ice_netdev_ops = {
.ndo_bpf = ice_xdp,
.ndo_xdp_xmit = ice_xdp_xmit,
.ndo_xsk_wakeup = ice_xsk_wakeup,
.ndo_hwtstamp_get = ice_ptp_hwtstamp_get,
.ndo_hwtstamp_set = ice_ptp_hwtstamp_set,
};

View File

@ -2197,23 +2197,24 @@ static int ice_ptp_getcrosststamp(struct ptp_clock_info *info,
}
/**
* ice_ptp_get_ts_config - ioctl interface to read the timestamping config
* @pf: Board private structure
* @ifr: ioctl data
* ice_ptp_hwtstamp_get - interface to read the timestamping config
* @netdev: Pointer to network interface device structure
* @config: Timestamping configuration structure
*
* Copy the timestamping config to user buffer
*/
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
int ice_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
struct hwtstamp_config *config;
struct ice_netdev_priv *np = netdev_priv(netdev);
struct ice_pf *pf = np->vsi->back;
if (pf->ptp.state != ICE_PTP_READY)
return -EIO;
config = &pf->ptp.tstamp_config;
*config = pf->ptp.tstamp_config;
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
-EFAULT : 0;
return 0;
}
/**
@ -2221,8 +2222,8 @@ int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
* @pf: Board private structure
* @config: hwtstamp settings requested or saved
*/
static int
ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
static int ice_ptp_set_timestamp_mode(struct ice_pf *pf,
struct kernel_hwtstamp_config *config)
{
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
@ -2266,32 +2267,32 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
}
/**
* ice_ptp_set_ts_config - ioctl interface to control the timestamping
* @pf: Board private structure
* @ifr: ioctl data
* ice_ptp_hwtstamp_set - interface to control the timestamping
* @netdev: Pointer to network interface device structure
* @config: Timestamping configuration structure
* @extack: Netlink extended ack structure for error reporting
*
* Get the user config and store it
*/
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
int ice_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct hwtstamp_config config;
struct ice_netdev_priv *np = netdev_priv(netdev);
struct ice_pf *pf = np->vsi->back;
int err;
if (pf->ptp.state != ICE_PTP_READY)
return -EAGAIN;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
err = ice_ptp_set_timestamp_mode(pf, &config);
err = ice_ptp_set_timestamp_mode(pf, config);
if (err)
return err;
/* Return the actual configuration set */
config = pf->ptp.tstamp_config;
*config = pf->ptp.tstamp_config;
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
return 0;
}
/**

View File

@ -259,7 +259,7 @@ struct ice_ptp {
struct ptp_extts_request extts_rqs[GLTSYN_EVNT_H_IDX_MAX];
struct ptp_clock_info info;
struct ptp_clock *clock;
struct hwtstamp_config tstamp_config;
struct kernel_hwtstamp_config tstamp_config;
u64 reset_time;
u32 tx_hwtstamp_skipped;
u32 tx_hwtstamp_timeouts;
@ -291,8 +291,11 @@ struct ice_ptp {
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
int ice_ptp_clock_index(struct ice_pf *pf);
struct ice_pf;
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr);
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr);
int ice_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config);
int ice_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
void ice_ptp_restore_timestamp_mode(struct ice_pf *pf);
void ice_ptp_extts_event(struct ice_pf *pf);
@ -313,12 +316,16 @@ void ice_ptp_init(struct ice_pf *pf);
void ice_ptp_release(struct ice_pf *pf);
void ice_ptp_link_change(struct ice_pf *pf, bool linkup);
#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
static inline int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
static inline int ice_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
return -EOPNOTSUPP;
}
static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
static inline int ice_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
return -EOPNOTSUPP;
}

View File

@ -626,7 +626,7 @@ struct igb_adapter {
struct delayed_work ptp_overflow_work;
struct work_struct ptp_tx_work;
struct sk_buff *ptp_tx_skb;
struct hwtstamp_config tstamp_config;
struct kernel_hwtstamp_config tstamp_config;
unsigned long ptp_tx_start;
unsigned long last_rx_ptp_check;
unsigned long last_rx_timestamp;
@ -771,8 +771,11 @@ void igb_ptp_tx_hang(struct igb_adapter *adapter);
void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb);
int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,
ktime_t *timestamp);
int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
int igb_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config);
int igb_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
void igb_set_flag_queue_pairs(struct igb_adapter *, const u32);
unsigned int igb_get_max_rss_queues(struct igb_adapter *);
#ifdef CONFIG_IGB_HWMON

View File

@ -3062,6 +3062,8 @@ static const struct net_device_ops igb_netdev_ops = {
.ndo_bpf = igb_xdp,
.ndo_xdp_xmit = igb_xdp_xmit,
.ndo_xsk_wakeup = igb_xsk_wakeup,
.ndo_hwtstamp_get = igb_ptp_hwtstamp_get,
.ndo_hwtstamp_set = igb_ptp_hwtstamp_set,
};
/**
@ -9317,10 +9319,6 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
case SIOCGMIIREG:
case SIOCSMIIREG:
return igb_mii_ioctl(netdev, ifr, cmd);
case SIOCGHWTSTAMP:
return igb_ptp_get_ts_config(netdev, ifr);
case SIOCSHWTSTAMP:
return igb_ptp_set_ts_config(netdev, ifr);
default:
return -EOPNOTSUPP;
}

View File

@ -1094,21 +1094,22 @@ void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb)
}
/**
* igb_ptp_get_ts_config - get hardware time stamping config
* igb_ptp_hwtstamp_get - get hardware time stamping config
* @netdev: netdev struct
* @ifr: interface struct
* @config: timestamping configuration structure
*
* Get the hwtstamp_config settings to return to the user. Rather than attempt
* to deconstruct the settings from the registers, just return a shadow copy
* of the last known settings.
**/
int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr)
int igb_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct hwtstamp_config *config = &adapter->tstamp_config;
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
-EFAULT : 0;
*config = adapter->tstamp_config;
return 0;
}
/**
@ -1129,7 +1130,7 @@ int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr)
* level 2 or 4".
*/
static int igb_ptp_set_timestamp_mode(struct igb_adapter *adapter,
struct hwtstamp_config *config)
struct kernel_hwtstamp_config *config)
{
struct e1000_hw *hw = &adapter->hw;
u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED;
@ -1275,30 +1276,26 @@ static int igb_ptp_set_timestamp_mode(struct igb_adapter *adapter,
}
/**
* igb_ptp_set_ts_config - set hardware time stamping config
* igb_ptp_hwtstamp_set - set hardware time stamping config
* @netdev: netdev struct
* @ifr: interface struct
*
* @config: timestamping configuration structure
* @extack: netlink extended ack structure for error reporting
**/
int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr)
int igb_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct hwtstamp_config config;
int err;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
err = igb_ptp_set_timestamp_mode(adapter, &config);
err = igb_ptp_set_timestamp_mode(adapter, config);
if (err)
return err;
/* save these settings for future reference */
memcpy(&adapter->tstamp_config, &config,
sizeof(adapter->tstamp_config));
adapter->tstamp_config = *config;
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
return 0;
}
/**

View File

@ -33,6 +33,7 @@ static const struct igbvf_stats igbvf_gstrings_stats[] = {
{ "lbrx_bytes", IGBVF_STAT(stats.gorlbc, stats.base_gorlbc) },
{ "lbrx_packets", IGBVF_STAT(stats.gprlbc, stats.base_gprlbc) },
{ "tx_restart_queue", IGBVF_STAT(restart_queue, zero_base) },
{ "tx_timeout_count", IGBVF_STAT(tx_timeout_count, zero_base) },
{ "rx_long_byte_count", IGBVF_STAT(stats.gorc, stats.base_gorc) },
{ "rx_csum_offload_good", IGBVF_STAT(hw_csum_good, zero_base) },
{ "rx_csum_offload_errors", IGBVF_STAT(hw_csum_err, zero_base) },

View File

@ -238,8 +238,6 @@ struct igbvf_adapter {
int int_mode;
u32 eims_enable_mask;
u32 eims_other;
u32 int_counter0;
u32 int_counter1;
u32 eeprom_wol;
u32 wol;

View File

@ -855,8 +855,6 @@ static irqreturn_t igbvf_msix_other(int irq, void *data)
struct igbvf_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
adapter->int_counter1++;
hw->mac.get_link_status = 1;
if (!test_bit(__IGBVF_DOWN, &adapter->state))
mod_timer(&adapter->watchdog_timer, jiffies + 1);
@ -899,8 +897,6 @@ static irqreturn_t igbvf_intr_msix_rx(int irq, void *data)
struct net_device *netdev = data;
struct igbvf_adapter *adapter = netdev_priv(netdev);
adapter->int_counter0++;
/* Write the ITR value calculated at the end of the
* previous interrupt.
*/

View File

@ -315,7 +315,7 @@ struct igc_adapter {
*/
spinlock_t ptp_tx_lock;
struct igc_tx_timestamp_request tx_tstamp[IGC_MAX_TX_TSTAMP_REGS];
struct hwtstamp_config tstamp_config;
struct kernel_hwtstamp_config tstamp_config;
unsigned int ptp_flags;
/* System time value lock */
spinlock_t tmreg_lock;
@ -773,8 +773,11 @@ void igc_ptp_reset(struct igc_adapter *adapter);
void igc_ptp_suspend(struct igc_adapter *adapter);
void igc_ptp_stop(struct igc_adapter *adapter);
ktime_t igc_ptp_rx_pktstamp(struct igc_adapter *adapter, __le32 *buf);
int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
int igc_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config);
int igc_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
void igc_ptp_tx_hang(struct igc_adapter *adapter);
void igc_ptp_read(struct igc_adapter *adapter, struct timespec64 *ts);
void igc_ptp_tx_tstamp_event(struct igc_adapter *adapter);

View File

@ -6303,24 +6303,6 @@ int igc_close(struct net_device *netdev)
return 0;
}
/**
* igc_ioctl - Access the hwtstamp interface
* @netdev: network interface device structure
* @ifr: interface request data
* @cmd: ioctl command
**/
static int igc_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
switch (cmd) {
case SIOCGHWTSTAMP:
return igc_ptp_get_ts_config(netdev, ifr);
case SIOCSHWTSTAMP:
return igc_ptp_set_ts_config(netdev, ifr);
default:
return -EOPNOTSUPP;
}
}
static int igc_save_launchtime_params(struct igc_adapter *adapter, int queue,
bool enable)
{
@ -6971,12 +6953,13 @@ static const struct net_device_ops igc_netdev_ops = {
.ndo_fix_features = igc_fix_features,
.ndo_set_features = igc_set_features,
.ndo_features_check = igc_features_check,
.ndo_eth_ioctl = igc_ioctl,
.ndo_setup_tc = igc_setup_tc,
.ndo_bpf = igc_bpf,
.ndo_xdp_xmit = igc_xdp_xmit,
.ndo_xsk_wakeup = igc_xsk_wakeup,
.ndo_get_tstamp = igc_get_tstamp,
.ndo_hwtstamp_get = igc_ptp_hwtstamp_get,
.ndo_hwtstamp_set = igc_ptp_hwtstamp_set,
};
u32 igc_rd32(struct igc_hw *hw, u32 reg)

View File

@ -626,7 +626,7 @@ static void igc_ptp_enable_tx_timestamp(struct igc_adapter *adapter)
* Return: 0 in case of success, negative errno code otherwise.
*/
static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter,
struct hwtstamp_config *config)
struct kernel_hwtstamp_config *config)
{
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
@ -853,48 +853,46 @@ void igc_ptp_tx_tstamp_event(struct igc_adapter *adapter)
}
/**
* igc_ptp_set_ts_config - set hardware time stamping config
* igc_ptp_hwtstamp_set - set hardware time stamping config
* @netdev: network interface device structure
* @ifr: interface request data
* @config: timestamping configuration structure
* @extack: netlink extended ack structure for error reporting
*
**/
int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr)
int igc_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct igc_adapter *adapter = netdev_priv(netdev);
struct hwtstamp_config config;
int err;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
err = igc_ptp_set_timestamp_mode(adapter, &config);
err = igc_ptp_set_timestamp_mode(adapter, config);
if (err)
return err;
/* save these settings for future reference */
memcpy(&adapter->tstamp_config, &config,
sizeof(adapter->tstamp_config));
adapter->tstamp_config = *config;
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
return 0;
}
/**
* igc_ptp_get_ts_config - get hardware time stamping config
* igc_ptp_hwtstamp_get - get hardware time stamping config
* @netdev: network interface device structure
* @ifr: interface request data
* @config: timestamping configuration structure
*
* Get the hwtstamp_config settings to return to the user. Rather than attempt
* to deconstruct the settings from the registers, just return a shadow copy
* of the last known settings.
**/
int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr)
int igc_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
struct igc_adapter *adapter = netdev_priv(netdev);
struct hwtstamp_config *config = &adapter->tstamp_config;
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
-EFAULT : 0;
*config = adapter->tstamp_config;
return 0;
}
/* The two conditions below must be met for cross timestamping via

View File

@ -429,6 +429,10 @@ enum ixgbe_ring_f_enum {
#define IXGBE_BAD_L2A_QUEUE 3
#define IXGBE_MAX_MACVLANS 63
#define IXGBE_MAX_TX_QUEUES 128
#define IXGBE_MAX_TX_DESCRIPTORS 40
#define IXGBE_MAX_TX_VF_HANGS 4
DECLARE_STATIC_KEY_FALSE(ixgbe_xdp_locking_key);
struct ixgbe_ring_feature {
@ -785,7 +789,7 @@ struct ixgbe_adapter {
struct ptp_clock_info ptp_caps;
struct work_struct ptp_tx_work;
struct sk_buff *ptp_tx_skb;
struct hwtstamp_config tstamp_config;
struct kernel_hwtstamp_config tstamp_config;
unsigned long ptp_tx_start;
unsigned long last_overflow_check;
unsigned long last_rx_ptp_check;
@ -810,6 +814,7 @@ struct ixgbe_adapter {
u32 timer_event_accumulator;
u32 vferr_refcount;
struct ixgbe_mac_addr *mac_table;
u8 tx_hang_count[IXGBE_MAX_TX_QUEUES];
struct kobject *info_kobj;
u16 lse_mask;
#ifdef CONFIG_IXGBE_HWMON
@ -1080,8 +1085,11 @@ static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
rx_ring->last_rx_timestamp = jiffies;
}
int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
int ixgbe_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config);
int ixgbe_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
void ixgbe_ptp_reset(struct ixgbe_adapter *adapter);
void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter);

View File

@ -45,7 +45,7 @@ static void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
goto out;
/*
* if capababilities version is type 1 we can write the
* if capabilities version is type 1 we can write the
* timeout of 10ms to 250ms through the GCR register
*/
if (!(gcr & IXGBE_GCR_CAP_VER2)) {
@ -751,7 +751,7 @@ static int ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
/*
* Store the original AUTOC value if it has not been
* stored off yet. Otherwise restore the stored original
* AUTOC value since the reset operation sets back to deaults.
* AUTOC value since the reset operation sets back to defaults.
*/
autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
if (hw->mac.orig_link_settings_stored == false) {

View File

@ -244,7 +244,7 @@ int ixgbe_setup_fc_generic(struct ixgbe_hw *hw)
*/
if (hw->phy.media_type == ixgbe_media_type_backplane) {
/* Need the SW/FW semaphore around AUTOC writes if 82599 and
* LESM is on, likewise reset_pipeline requries the lock as
* LESM is on, likewise reset_pipeline requires the lock as
* it also writes AUTOC.
*/
ret_val = hw->mac.ops.prot_autoc_write(hw, reg_bp, locked);
@ -301,7 +301,7 @@ int ixgbe_start_hw_generic(struct ixgbe_hw *hw)
return ret_val;
}
/* Cashe bit indicating need for crosstalk fix */
/* Cache bit indicating need for crosstalk fix */
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X550EM_x:

View File

@ -3965,6 +3965,10 @@ static const struct ixgbe_mac_operations mac_ops_e610 = {
.prot_autoc_write = prot_autoc_write_generic,
.setup_fc = ixgbe_setup_fc_e610,
.fc_autoneg = ixgbe_fc_autoneg_e610,
.enable_mdd = ixgbe_enable_mdd_x550,
.disable_mdd = ixgbe_disable_mdd_x550,
.restore_mdd_vf = ixgbe_restore_mdd_vf_x550,
.handle_mdd = ixgbe_handle_mdd_x550,
};
static const struct ixgbe_phy_operations phy_ops_e610 = {

View File

@ -744,7 +744,7 @@ void ixgbe_free_fcoe_ddp_resources(struct ixgbe_adapter *adapter)
* ixgbe_setup_fcoe_ddp_resources - setup all fcoe ddp context resources
* @adapter: ixgbe adapter
*
* Sets up ddp context resouces
* Sets up ddp context resources
*
* Returns : 0 indicates success or -EINVAL on failure
*/

View File

@ -891,7 +891,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
q_vector->rx.itr = IXGBE_ITR_ADAPTIVE_MAX_USECS |
IXGBE_ITR_ADAPTIVE_LATENCY;
/* intialize ITR */
/* initialize ITR */
if (txr_count && !rxr_count) {
/* tx only vector */
if (adapter->tx_itr_setting == 1)
@ -1293,7 +1293,8 @@ void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
tx_ring->next_to_use = (i < tx_ring->count) ? i : 0;
/* set bits to identify this as an advanced context descriptor */
type_tucmd |= IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
type_tucmd |= IXGBE_TXD_CMD_DEXT |
FIELD_PREP(IXGBE_ADVTXD_DTYP_MASK, IXGBE_ADVTXD_DTYP_CTXT);
context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
context_desc->fceof_saidx = cpu_to_le32(fceof_saidx);

View File

@ -9,6 +9,7 @@
#include <linux/string.h>
#include <linux/in.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/sctp.h>
@ -1040,6 +1041,48 @@ static u64 ixgbe_get_tx_pending(struct ixgbe_ring *ring)
return ((head <= tail) ? tail : tail + ring->count) - head;
}
/**
* ixgbe_get_vf_idx - provide VF index number based on queue index
* @adapter: pointer to the adapter struct
* @queue: Tx queue identifier
* @vf: output VF index
*
* Provide VF index number associated to the input queue.
*
* Returns: 0 if VF provided or error number.
*/
static int ixgbe_get_vf_idx(struct ixgbe_adapter *adapter, u16 queue, u16 *vf)
{
struct ixgbe_hw *hw = &adapter->hw;
u8 queue_count;
u32 reg;
if (queue >= adapter->num_tx_queues)
return -EINVAL;
/* Determine number of queues by checking
* number of virtual functions
*/
reg = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
switch (reg & IXGBE_GCR_EXT_VT_MODE_MASK) {
case IXGBE_GCR_EXT_VT_MODE_64:
queue_count = IXGBE_64VFS_QUEUES;
break;
case IXGBE_GCR_EXT_VT_MODE_32:
queue_count = IXGBE_32VFS_QUEUES;
break;
case IXGBE_GCR_EXT_VT_MODE_16:
queue_count = IXGBE_16VFS_QUEUES;
break;
default:
return -EINVAL;
}
*vf = queue / queue_count;
return 0;
}
static bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring)
{
u32 tx_done = ixgbe_get_tx_completed(tx_ring);
@ -1158,6 +1201,150 @@ void ixgbe_update_rx_ring_stats(struct ixgbe_ring *rx_ring,
q_vector->rx.total_packets += pkts;
}
/**
* ixgbe_pf_handle_tx_hang - handle Tx hang on PF
* @tx_ring: tx ring number
* @next: next ring
*
* Prints a message containing details about the tx hang.
*/
static void ixgbe_pf_handle_tx_hang(struct ixgbe_ring *tx_ring,
unsigned int next)
{
struct ixgbe_adapter *adapter = netdev_priv(tx_ring->netdev);
struct ixgbe_hw *hw = &adapter->hw;
e_err(drv, "Detected Tx Unit Hang%s\n"
" Tx Queue <%d>\n"
" TDH, TDT <%x>, <%x>\n"
" next_to_use <%x>\n"
" next_to_clean <%x>\n"
"tx_buffer_info[next_to_clean]\n"
" time_stamp <%lx>\n"
" jiffies <%lx>\n",
ring_is_xdp(tx_ring) ? " (XDP)" : "",
tx_ring->queue_index,
IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)),
IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)),
tx_ring->next_to_use, next,
tx_ring->tx_buffer_info[next].time_stamp, jiffies);
if (!ring_is_xdp(tx_ring))
netif_stop_subqueue(tx_ring->netdev,
tx_ring->queue_index);
}
/**
* ixgbe_vf_handle_tx_hang - handle Tx hang on VF
* @adapter: structure containing ring specific data
* @vf: VF index
*
* Print a message containing details about malicious driver detection.
* Set malicious VF link down if the detection happened several times.
*/
static void ixgbe_vf_handle_tx_hang(struct ixgbe_adapter *adapter, u16 vf)
{
struct ixgbe_hw *hw = &adapter->hw;
if (adapter->hw.mac.type != ixgbe_mac_e610)
return;
e_warn(drv,
"Malicious Driver Detection tx hang detected on PF %d VF %d MAC: %pM",
hw->bus.func, vf, adapter->vfinfo[vf].vf_mac_addresses);
adapter->tx_hang_count[vf]++;
if (adapter->tx_hang_count[vf] == IXGBE_MAX_TX_VF_HANGS) {
ixgbe_set_vf_link_state(adapter, vf,
IFLA_VF_LINK_STATE_DISABLE);
adapter->tx_hang_count[vf] = 0;
}
}
static u32 ixgbe_poll_tx_icache(struct ixgbe_hw *hw, u16 queue, u16 idx)
{
IXGBE_WRITE_REG(hw, IXGBE_TXDESCIC, queue * idx);
return IXGBE_READ_REG(hw, IXGBE_TXDESCIC);
}
/**
* ixgbe_check_illegal_queue - search for queue with illegal packet
* @adapter: structure containing ring specific data
* @queue: queue index
*
* Check if tx descriptor connected with input queue
* contains illegal packet.
*
* Returns: true if queue contain illegal packet.
*/
static bool ixgbe_check_illegal_queue(struct ixgbe_adapter *adapter,
u16 queue)
{
u32 hdr_len_reg, mss_len_reg, type_reg;
struct ixgbe_hw *hw = &adapter->hw;
u32 mss_len, header_len, reg;
for (u16 i = 0; i < IXGBE_MAX_TX_DESCRIPTORS; i++) {
/* HW will clear bit IXGBE_TXDESCIC_READY when address
* is written to address field. HW will set this bit
* when iCache read is done, and data is ready at TIC_DWx.
* Set descriptor address.
*/
read_poll_timeout(ixgbe_poll_tx_icache, reg,
!(reg & IXGBE_TXDESCIC_READY), 0, 0, false,
hw, queue, i);
/* read tx descriptor access registers */
hdr_len_reg = IXGBE_READ_REG(hw, IXGBE_TIC_DW2(IXGBE_VLAN_MACIP_LENS_REG));
type_reg = IXGBE_READ_REG(hw, IXGBE_TIC_DW2(IXGBE_TYPE_TUCMD_MLHL));
mss_len_reg = IXGBE_READ_REG(hw, IXGBE_TIC_DW2(IXGBE_MSS_L4LEN_IDX));
/* check if Advanced Context Descriptor */
if (FIELD_GET(IXGBE_ADVTXD_DTYP_MASK, type_reg) !=
IXGBE_ADVTXD_DTYP_CTXT)
continue;
/* check for illegal MSS and Header length */
mss_len = FIELD_GET(IXGBE_ADVTXD_MSS_MASK, mss_len_reg);
header_len = FIELD_GET(IXGBE_ADVTXD_HEADER_LEN_MASK,
hdr_len_reg);
if ((mss_len + header_len) > SZ_16K) {
e_warn(probe, "mss len + header len too long\n");
return true;
}
}
return false;
}
/**
* ixgbe_handle_mdd_event - handle mdd event
* @adapter: structure containing ring specific data
* @tx_ring: tx descriptor ring to handle
*
* Reset VF driver if malicious vf detected or
* illegal packet in an any queue detected.
*/
static void ixgbe_handle_mdd_event(struct ixgbe_adapter *adapter,
struct ixgbe_ring *tx_ring)
{
u16 vf, q;
if (adapter->vfinfo && ixgbe_check_mdd_event(adapter)) {
/* vf mdd info and malicious vf detected */
if (!ixgbe_get_vf_idx(adapter, tx_ring->queue_index, &vf))
ixgbe_vf_handle_tx_hang(adapter, vf);
} else {
/* malicious vf not detected */
for (q = 0; q < IXGBE_MAX_TX_QUEUES; q++) {
if (ixgbe_check_illegal_queue(adapter, q) &&
!ixgbe_get_vf_idx(adapter, q, &vf))
/* illegal queue detected */
ixgbe_vf_handle_tx_hang(adapter, vf);
}
}
}
/**
* ixgbe_clean_tx_irq - Reclaim resources after transmit completes
* @q_vector: structure containing interrupt and ring information
@ -1265,26 +1452,10 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
adapter->tx_ipsec += total_ipsec;
if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) {
/* schedule immediate reset if we believe we hung */
struct ixgbe_hw *hw = &adapter->hw;
e_err(drv, "Detected Tx Unit Hang %s\n"
" Tx Queue <%d>\n"
" TDH, TDT <%x>, <%x>\n"
" next_to_use <%x>\n"
" next_to_clean <%x>\n"
"tx_buffer_info[next_to_clean]\n"
" time_stamp <%lx>\n"
" jiffies <%lx>\n",
ring_is_xdp(tx_ring) ? "(XDP)" : "",
tx_ring->queue_index,
IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)),
IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)),
tx_ring->next_to_use, i,
tx_ring->tx_buffer_info[i].time_stamp, jiffies);
if (adapter->hw.mac.type == ixgbe_mac_e610)
ixgbe_handle_mdd_event(adapter, tx_ring);
if (!ring_is_xdp(tx_ring))
netif_stop_subqueue(tx_ring->netdev,
tx_ring->queue_index);
ixgbe_pf_handle_tx_hang(tx_ring, i);
e_info(probe,
"tx hang %d detected on queue %d, resetting adapter\n",
@ -2200,7 +2371,7 @@ static struct sk_buff *ixgbe_build_skb(struct ixgbe_ring *rx_ring,
struct sk_buff *skb;
/* Prefetch first cache line of first page. If xdp->data_meta
* is unused, this points extactly as xdp->data, otherwise we
* is unused, this points exactly as xdp->data, otherwise we
* likely have a consumer accessing first few bytes of meta
* data, and then actual data.
*/
@ -2323,7 +2494,7 @@ static void ixgbe_rx_buffer_flip(struct ixgbe_ring *rx_ring,
* This function provides a "bounce buffer" approach to Rx interrupt
* processing. The advantage to this is that on systems that have
* expensive overhead for IOMMU access this provides a means of avoiding
* it by maintaining the mapping of the page to the syste.
* it by maintaining the mapping of the page to the system.
*
* Returns amount of work completed
**/
@ -3933,8 +4104,12 @@ void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter)
static void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter)
#endif
{
int i;
bool pfc_en = adapter->dcb_cfg.pfc_mode_enable;
struct ixgbe_hw *hw = &adapter->hw;
int i;
if (hw->mac.ops.disable_mdd)
hw->mac.ops.disable_mdd(hw);
if (adapter->ixgbe_ieee_pfc)
pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en);
@ -3956,6 +4131,9 @@ static void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter)
for (i = 0; i < adapter->num_rx_queues; i++)
ixgbe_disable_rx_drop(adapter, adapter->rx_ring[i]);
}
if (hw->mac.ops.enable_mdd)
hw->mac.ops.enable_mdd(hw);
}
#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
@ -4885,7 +5063,7 @@ static void ixgbe_scrub_vfta(struct ixgbe_adapter *adapter, u32 vfta_offset)
/* pull VLAN ID from VLVF */
vid = vlvf & VLAN_VID_MASK;
/* only concern outselves with a certain range */
/* only concern ourselves with a certain range */
if (vid < vid_start || vid >= vid_end)
continue;
@ -7964,6 +8142,9 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
netif_carrier_on(netdev);
ixgbe_check_vf_rate_limit(adapter);
if (adapter->num_vfs && hw->mac.ops.enable_mdd)
hw->mac.ops.enable_mdd(hw);
/* enable transmits */
netif_tx_wake_all_queues(adapter->netdev);
@ -9441,10 +9622,6 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
switch (cmd) {
case SIOCSHWTSTAMP:
return ixgbe_ptp_set_ts_config(adapter, req);
case SIOCGHWTSTAMP:
return ixgbe_ptp_get_ts_config(adapter, req);
case SIOCGMIIPHY:
if (!adapter->hw.phy.ops.read_reg)
return -EOPNOTSUPP;
@ -10908,6 +11085,8 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_bpf = ixgbe_xdp,
.ndo_xdp_xmit = ixgbe_xdp_xmit,
.ndo_xsk_wakeup = ixgbe_xsk_wakeup,
.ndo_hwtstamp_get = ixgbe_ptp_hwtstamp_get,
.ndo_hwtstamp_set = ixgbe_ptp_hwtstamp_set,
};
static void ixgbe_disable_txr_hw(struct ixgbe_adapter *adapter,
@ -11110,7 +11289,7 @@ void ixgbe_txrx_ring_enable(struct ixgbe_adapter *adapter, int ring)
* ixgbe_enumerate_functions - Get the number of ports this device has
* @adapter: adapter structure
*
* This function enumerates the phsyical functions co-located on a single slot,
* This function enumerates the physical functions co-located on a single slot,
* in order to determine how many ports a device has. This is most useful in
* determining the required GT/s of PCIe bandwidth necessary for optimal
* performance.

View File

@ -34,7 +34,7 @@
#define IXGBE_VT_MSGTYPE_CTS 0x20000000 /* Indicates that VF is still
clear to send requests */
#define IXGBE_VT_MSGINFO_SHIFT 16
/* bits 23:16 are used for exra info for certain messages */
/* bits 23:16 are used for extra info for certain messages */
#define IXGBE_VT_MSGINFO_MASK (0xFF << IXGBE_VT_MSGINFO_SHIFT)
/* definitions to support mailbox API version negotiation */

View File

@ -1323,7 +1323,7 @@ int ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
* @hw: pointer to hardware structure
*
* Restart autonegotiation and PHY and waits for completion.
* This function always returns success, this is nessary since
* This function always returns success, this is necessary since
* it is called via a function pointer that could call other
* functions that could return an error.
**/

View File

@ -936,20 +936,22 @@ void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *q_vector,
}
/**
* ixgbe_ptp_get_ts_config - get current hardware timestamping configuration
* @adapter: pointer to adapter structure
* @ifr: ioctl data
* ixgbe_ptp_hwtstamp_get - get current hardware timestamping configuration
* @netdev: pointer to net device structure
* @config: timestamping configuration structure
*
* This function returns the current timestamping settings. Rather than
* attempt to deconstruct registers to fill in the values, simply keep a copy
* of the old settings around, and return a copy when requested.
*/
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
int ixgbe_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
struct hwtstamp_config *config = &adapter->tstamp_config;
struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
return copy_to_user(ifr->ifr_data, config,
sizeof(*config)) ? -EFAULT : 0;
*config = adapter->tstamp_config;
return 0;
}
/**
@ -978,7 +980,7 @@ int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
* mode, if required to support the specifically requested mode.
*/
static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
struct hwtstamp_config *config)
struct kernel_hwtstamp_config *config)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED;
@ -1129,31 +1131,29 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
}
/**
* ixgbe_ptp_set_ts_config - user entry point for timestamp mode
* @adapter: pointer to adapter struct
* @ifr: ioctl data
* ixgbe_ptp_hwtstamp_set - user entry point for timestamp mode
* @netdev: pointer to net device structure
* @config: timestamping configuration structure
* @extack: netlink extended ack structure for error reporting
*
* Set hardware to requested mode. If unsupported, return an error with no
* changes. Otherwise, store the mode for future reference.
*/
int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
int ixgbe_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct hwtstamp_config config;
struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
int err;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
err = ixgbe_ptp_set_timestamp_mode(adapter, &config);
err = ixgbe_ptp_set_timestamp_mode(adapter, config);
if (err)
return err;
/* save these settings for future reference */
memcpy(&adapter->tstamp_config, &config,
sizeof(adapter->tstamp_config));
adapter->tstamp_config = *config;
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
return 0;
}
static void ixgbe_ptp_link_speed_adjust(struct ixgbe_adapter *adapter,

View File

@ -207,6 +207,7 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsigned int max_vfs)
int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
{
unsigned int num_vfs = adapter->num_vfs, vf;
struct ixgbe_hw *hw = &adapter->hw;
unsigned long flags;
int rss;
@ -237,6 +238,9 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
return 0;
if (hw->mac.ops.disable_mdd)
hw->mac.ops.disable_mdd(hw);
#ifdef CONFIG_PCI_IOV
/*
* If our VFs are assigned we cannot shut down SR-IOV
@ -702,7 +706,7 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
u32 reg_val;
u32 queue;
/* remove VLAN filters beloning to this VF */
/* remove VLAN filters belonging to this VF */
ixgbe_clear_vf_vlans(adapter, vf);
/* add back PF assigned VLAN or VLAN 0 */
@ -1353,12 +1357,59 @@ static void ixgbe_rcv_ack_from_vf(struct ixgbe_adapter *adapter, u32 vf)
ixgbe_write_mbx(hw, &msg, 1, vf);
}
/**
* ixgbe_check_mdd_event - check for MDD event on all VFs
* @adapter: pointer to ixgbe adapter
*
* Return: true if there is a VF on which MDD event occurred, false otherwise.
*/
bool ixgbe_check_mdd_event(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
DECLARE_BITMAP(vf_bitmap, 64);
bool ret = false;
int i;
if (!hw->mac.ops.handle_mdd)
return false;
/* Did we have a malicious event */
bitmap_zero(vf_bitmap, 64);
hw->mac.ops.handle_mdd(hw, vf_bitmap);
/* Log any blocked queues and release lock */
for_each_set_bit(i, vf_bitmap, 64) {
dev_warn(&adapter->pdev->dev,
"Malicious event on VF %d tx:%x rx:%x\n", i,
IXGBE_READ_REG(hw, IXGBE_LVMMC_TX),
IXGBE_READ_REG(hw, IXGBE_LVMMC_RX));
if (hw->mac.ops.restore_mdd_vf) {
u32 ping;
hw->mac.ops.restore_mdd_vf(hw, i);
/* get the VF to rebuild its queues */
adapter->vfinfo[i].clear_to_send = 0;
ping = IXGBE_PF_CONTROL_MSG |
IXGBE_VT_MSGTYPE_CTS;
ixgbe_write_mbx(hw, &ping, 1, i);
}
ret = true;
}
return ret;
}
void ixgbe_msg_task(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
unsigned long flags;
u32 vf;
ixgbe_check_mdd_event(adapter);
spin_lock_irqsave(&adapter->vfs_lock, flags);
for (vf = 0; vf < adapter->num_vfs; vf++) {
/* process any reset requests */

View File

@ -15,6 +15,7 @@
#ifdef CONFIG_PCI_IOV
void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter);
#endif
bool ixgbe_check_mdd_event(struct ixgbe_adapter *adapter);
void ixgbe_msg_task(struct ixgbe_adapter *adapter);
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);

View File

@ -238,7 +238,7 @@ struct ixgbe_thermal_sensor_data {
#define NVM_VER_INVALID 0xFFFF
#define NVM_ETK_VALID 0x8000
#define NVM_INVALID_PTR 0xFFFF
#define NVM_VER_SIZE 32 /* version sting size */
#define NVM_VER_SIZE 32 /* version string size */
struct ixgbe_nvm_version {
u32 etk_id;
@ -402,6 +402,8 @@ struct ixgbe_nvm_version {
#define IXGBE_MRCTL(_i) (0x0F600 + ((_i) * 4))
#define IXGBE_VMRVLAN(_i) (0x0F610 + ((_i) * 4))
#define IXGBE_VMRVM(_i) (0x0F630 + ((_i) * 4))
#define IXGBE_LVMMC_RX 0x2FA8
#define IXGBE_LVMMC_TX 0x8108
#define IXGBE_WQBR_RX(_i) (0x2FB0 + ((_i) * 4)) /* 4 total */
#define IXGBE_WQBR_TX(_i) (0x8130 + ((_i) * 4)) /* 4 total */
#define IXGBE_L34T_IMIR(_i) (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
@ -1042,6 +1044,7 @@ struct ixgbe_nvm_version {
#define IXGBE_GCR_EXT_VT_MODE_16 0x00000001
#define IXGBE_GCR_EXT_VT_MODE_32 0x00000002
#define IXGBE_GCR_EXT_VT_MODE_64 0x00000003
#define IXGBE_GCR_EXT_VT_MODE_MASK 0x00000003
#define IXGBE_GCR_EXT_SRIOV (IXGBE_GCR_EXT_MSIX_EN | \
IXGBE_GCR_EXT_VT_MODE_64)
@ -2021,7 +2024,7 @@ enum {
/* EEPROM Addressing bits based on type (0-small, 1-large) */
#define IXGBE_EEC_ADDR_SIZE 0x00000400
#define IXGBE_EEC_SIZE 0x00007800 /* EEPROM Size */
#define IXGBE_EERD_MAX_ADDR 0x00003FFF /* EERD alows 14 bits for addr. */
#define IXGBE_EERD_MAX_ADDR 0x00003FFF /* EERD allows 14 bits for addr. */
#define IXGBE_EEC_SIZE_SHIFT 11
#define IXGBE_EEPROM_WORD_SIZE_SHIFT 6
@ -2746,6 +2749,28 @@ enum ixgbe_fdir_pballoc_type {
#define FW_PHY_INFO_ID_HI_MASK 0xFFFF0000u
#define FW_PHY_INFO_ID_LO_MASK 0x0000FFFFu
/* There are only 3 options for VFs creation on this device:
* 16 VFs pool with 8 queues each
* 32 VFs pool with 4 queues each
* 64 VFs pool with 2 queues each
*
* That means reading some VF registers that map VF to queue depending on
* chosen option. Define values that help dealing with each scenario.
*/
/* Number of queues based on VFs pool */
#define IXGBE_16VFS_QUEUES 8
#define IXGBE_32VFS_QUEUES 4
#define IXGBE_64VFS_QUEUES 2
/* Mask for getting queues bits based on VFs pool */
#define IXGBE_16VFS_BITMASK GENMASK(IXGBE_16VFS_QUEUES - 1, 0)
#define IXGBE_32VFS_BITMASK GENMASK(IXGBE_32VFS_QUEUES - 1, 0)
#define IXGBE_64VFS_BITMASK GENMASK(IXGBE_64VFS_QUEUES - 1, 0)
/* Convert queue index to register number.
* We have 4 registers with 32 queues in each.
*/
#define IXGBE_QUEUES_PER_REG 32
#define IXGBE_QUEUES_REG_AMOUNT 4
/* Host Interface Command Structures */
struct ixgbe_hic_hdr {
u8 cmd;
@ -2911,6 +2936,13 @@ struct ixgbe_adv_tx_context_desc {
__le32 mss_l4len_idx;
};
enum {
IXGBE_VLAN_MACIP_LENS_REG = 0,
IXGBE_FCEOF_SAIDX_REG = 1,
IXGBE_TYPE_TUCMD_MLHL = 2,
IXGBE_MSS_L4LEN_IDX = 3,
};
/* Adv Transmit Descriptor Config Masks */
#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */
#define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */
@ -2918,7 +2950,7 @@ struct ixgbe_adv_tx_context_desc {
#define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */
#define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */
#define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */
#define IXGBE_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Desc */
#define IXGBE_ADVTXD_DTYP_CTXT 0x2 /* Advanced Context Desc */
#define IXGBE_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define IXGBE_ADVTXD_DCMD_EOP IXGBE_TXD_CMD_EOP /* End of Packet */
#define IXGBE_ADVTXD_DCMD_IFCS IXGBE_TXD_CMD_IFCS /* Insert FCS */
@ -2967,6 +2999,8 @@ struct ixgbe_adv_tx_context_desc {
#define IXGBE_ADVTXD_FCOEF_EOF_MASK (3u << 10) /* FC EOF index */
#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
#define IXGBE_ADVTXD_MSS_MASK GENMASK(31, IXGBE_ADVTXD_MSS_SHIFT)
#define IXGBE_ADVTXD_HEADER_LEN_MASK GENMASK(8, 0)
/* Autonegotiation advertised speeds */
typedef u32 ixgbe_autoneg_advertised;
@ -3539,6 +3573,12 @@ struct ixgbe_mac_operations {
int (*dmac_config_tcs)(struct ixgbe_hw *hw);
int (*read_iosf_sb_reg)(struct ixgbe_hw *, u32, u32, u32 *);
int (*write_iosf_sb_reg)(struct ixgbe_hw *, u32, u32, u32);
/* MDD events */
void (*enable_mdd)(struct ixgbe_hw *hw);
void (*disable_mdd)(struct ixgbe_hw *hw);
void (*restore_mdd_vf)(struct ixgbe_hw *hw, u32 vf);
void (*handle_mdd)(struct ixgbe_hw *hw, unsigned long *vf_bitmap);
};
struct ixgbe_phy_operations {

View File

@ -47,7 +47,7 @@ int ixgbe_get_invariants_X540(struct ixgbe_hw *hw)
}
/**
* ixgbe_setup_mac_link_X540 - Set the auto advertised capabilitires
* ixgbe_setup_mac_link_X540 - Set the auto advertised capabilities
* @hw: pointer to hardware structure
* @speed: new link speed
* @autoneg_wait_to_complete: true when waiting for completion is needed

View File

@ -3316,7 +3316,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
return media_type;
}
/** ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
/** ixgbe_init_ext_t_x550em - Start (uninstall) the external Base T PHY.
** @hw: pointer to hardware structure
**/
static int ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
@ -3800,6 +3800,122 @@ static int ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
return status;
}
static void ixgbe_set_mdd_x550(struct ixgbe_hw *hw, bool ena)
{
u32 reg_dma, reg_rdr;
reg_dma = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
reg_rdr = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
if (ena) {
reg_dma |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
reg_rdr |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
} else {
reg_dma &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
reg_rdr &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
}
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_dma);
IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg_rdr);
}
/**
* ixgbe_enable_mdd_x550 - enable malicious driver detection
* @hw: pointer to hardware structure
*/
void ixgbe_enable_mdd_x550(struct ixgbe_hw *hw)
{
ixgbe_set_mdd_x550(hw, true);
}
/**
* ixgbe_disable_mdd_x550 - disable malicious driver detection
* @hw: pointer to hardware structure
*/
void ixgbe_disable_mdd_x550(struct ixgbe_hw *hw)
{
ixgbe_set_mdd_x550(hw, false);
}
/**
* ixgbe_restore_mdd_vf_x550 - restore VF that was disabled during MDD event
* @hw: pointer to hardware structure
* @vf: vf index
*/
void ixgbe_restore_mdd_vf_x550(struct ixgbe_hw *hw, u32 vf)
{
u32 idx, reg, val, num_qs, start_q, bitmask;
/* Map VF to queues */
reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
switch (reg & IXGBE_MRQC_MRQE_MASK) {
case IXGBE_MRQC_VMDQRT8TCEN:
num_qs = IXGBE_16VFS_QUEUES;
bitmask = IXGBE_16VFS_BITMASK;
break;
case IXGBE_MRQC_VMDQRSS32EN:
case IXGBE_MRQC_VMDQRT4TCEN:
num_qs = IXGBE_32VFS_QUEUES;
bitmask = IXGBE_32VFS_BITMASK;
break;
default:
num_qs = IXGBE_64VFS_QUEUES;
bitmask = IXGBE_64VFS_BITMASK;
break;
}
start_q = vf * num_qs;
/* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */
idx = start_q / IXGBE_QUEUES_PER_REG;
val = bitmask << (start_q % IXGBE_QUEUES_PER_REG);
IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), val);
IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), val);
}
/**
* ixgbe_handle_mdd_x550 - handle malicious driver detection event
* @hw: pointer to hardware structure
* @vf_bitmap: output vf bitmap of malicious vfs
*/
void ixgbe_handle_mdd_x550(struct ixgbe_hw *hw, unsigned long *vf_bitmap)
{
u32 i, j, reg, q, div, vf;
unsigned long wqbr;
/* figure out pool size for mapping to vf's */
reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
switch (reg & IXGBE_MRQC_MRQE_MASK) {
case IXGBE_MRQC_VMDQRT8TCEN:
div = IXGBE_16VFS_QUEUES;
break;
case IXGBE_MRQC_VMDQRSS32EN:
case IXGBE_MRQC_VMDQRT4TCEN:
div = IXGBE_32VFS_QUEUES;
break;
default:
div = IXGBE_64VFS_QUEUES;
break;
}
/* Read WQBR_TX and WQBR_RX and check for malicious queues */
for (i = 0; i < IXGBE_QUEUES_REG_AMOUNT; i++) {
wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i)) |
IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i));
if (!wqbr)
continue;
/* Get malicious queue */
for_each_set_bit(j, (unsigned long *)&wqbr,
IXGBE_QUEUES_PER_REG) {
/* Get queue from bitmask */
q = j + (i * IXGBE_QUEUES_PER_REG);
/* Map queue to vf */
vf = q / div;
set_bit(vf, vf_bitmap);
}
}
}
#define X550_COMMON_MAC \
.init_hw = &ixgbe_init_hw_generic, \
.start_hw = &ixgbe_start_hw_X540, \
@ -3863,6 +3979,10 @@ static const struct ixgbe_mac_operations mac_ops_X550 = {
.prot_autoc_write = prot_autoc_write_generic,
.setup_fc = ixgbe_setup_fc_generic,
.fc_autoneg = ixgbe_fc_autoneg,
.enable_mdd = ixgbe_enable_mdd_x550,
.disable_mdd = ixgbe_disable_mdd_x550,
.restore_mdd_vf = ixgbe_restore_mdd_vf_x550,
.handle_mdd = ixgbe_handle_mdd_x550,
};
static const struct ixgbe_mac_operations mac_ops_X550EM_x = {

View File

@ -17,4 +17,9 @@ void ixgbe_set_source_address_pruning_x550(struct ixgbe_hw *hw,
void ixgbe_set_ethertype_anti_spoofing_x550(struct ixgbe_hw *hw,
bool enable, int vf);
void ixgbe_enable_mdd_x550(struct ixgbe_hw *hw);
void ixgbe_disable_mdd_x550(struct ixgbe_hw *hw);
void ixgbe_restore_mdd_vf_x550(struct ixgbe_hw *hw, u32 vf);
void ixgbe_handle_mdd_x550(struct ixgbe_hw *hw, unsigned long *vf_bitmap);
#endif /* _IXGBE_X550_H_ */